diff --git a/help/reference/shell/evince-docs.xml b/help/reference/shell/evince-docs.xml
index 052ab206..7c1036f3 100644
--- a/help/reference/shell/evince-docs.xml
+++ b/help/reference/shell/evince-docs.xml
@@ -93,11 +93,9 @@
-
-
diff --git a/help/reference/shell/evince-sections.txt b/help/reference/shell/evince-sections.txt
index a775f7e2..1bf89a5d 100644
--- a/help/reference/shell/evince-sections.txt
+++ b/help/reference/shell/evince-sections.txt
@@ -365,23 +365,6 @@ EV_IS_MEDIA_PLAYER_KEYS_CLASS
EV_MEDIA_PLAYER_KEYS_GET_CLASS
-
-ev-navigation-action
-EvNavigationAction
-EvNavigationAction
-EvNavigationActionPrivate
-EvNavigationActionClass
-ev_navigation_action_set_history
-
-EV_NAVIGATION_ACTION
-EV_IS_NAVIGATION_ACTION
-EV_TYPE_NAVIGATION_ACTION
-ev_navigation_action_get_type
-EV_NAVIGATION_ACTION_CLASS
-EV_IS_NAVIGATION_ACTION_CLASS
-EV_NAVIGATION_ACTION_GET_CLASS
-
-
ev-file-monitor
EvFileMonitor
@@ -429,17 +412,6 @@ ev_window_title_set_uri
ev_window_title_free
-
-ev-navigation-action-widget
-EvNavigationActionWidget
-EV_TYPE_NAVIGATION_ACTION_WIDGET
-EV_NAVIGATION_ACTION_WIDGET
-EvNavigationActionWidget
-EvNavigationActionWidgetClass
-ev_navigation_action_widget_get_type
-ev_navigation_action_widget_set_menu
-
-
ev-keyring
ev_keyring_is_available
diff --git a/help/reference/shell/evince.types b/help/reference/shell/evince.types
index dea7db50..1df224b7 100644
--- a/help/reference/shell/evince.types
+++ b/help/reference/shell/evince.types
@@ -5,8 +5,6 @@ ev_history_get_type
ev_media_player_keys_get_type
ev_message_area_get_type
ev_metadata_get_type
-ev_navigation_action_get_type
-ev_navigation_action_widget_get_type
ev_open_recent_action_get_type
ev_page_action_get_type
ev_page_action_widget_get_type
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e09f2faf..5455485f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -36,10 +36,9 @@ shell/eggfindbar.c
shell/ev-annotation-properties-dialog.c
shell/ev-application.c
shell/ev-history.c
+shell/ev-history-action-widget.c
shell/ev-keyring.c
shell/ev-loading-message.c
-shell/ev-navigation-action.c
-shell/ev-navigation-action-widget.c
shell/ev-open-recent-action.c
shell/ev-password-view.c
shell/ev-properties-dialog.c
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 38952b66..1ec8ddeb 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -39,6 +39,10 @@ evince_SOURCES= \
ev-file-monitor.c \
ev-history.c \
ev-history.h \
+ ev-history-action.c \
+ ev-history-action.h \
+ ev-history-action-widget.c \
+ ev-history-action-widget.h \
ev-keyring.h \
ev-keyring.c \
ev-loading-message.c \
@@ -47,10 +51,6 @@ evince_SOURCES= \
ev-message-area.h \
ev-metadata.c \
ev-metadata.h \
- ev-navigation-action.c \
- ev-navigation-action.h \
- ev-navigation-action-widget.c \
- ev-navigation-action-widget.h \
ev-password-view.h \
ev-password-view.c \
ev-progress-message-area.h \
diff --git a/shell/ev-history-action-widget.c b/shell/ev-history-action-widget.c
new file mode 100644
index 00000000..fc3a707b
--- /dev/null
+++ b/shell/ev-history-action-widget.c
@@ -0,0 +1,331 @@
+/* ev-history-action-widget.c
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2013 Carlos Garcia Campos
+ *
+ * Evince 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.
+ *
+ * Evince 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.
+ */
+
+#include "config.h"
+
+#include "ev-history-action-widget.h"
+
+#include
+#include
+
+
+enum {
+ PROP_0,
+
+ PROP_POPUP_SHOWN
+};
+
+struct _EvHistoryActionWidgetPrivate {
+ GtkWidget *back_button;
+ GtkWidget *forward_button;
+
+ EvHistory *history;
+ gboolean popup_shown;
+};
+
+typedef enum {
+ EV_HISTORY_ACTION_BUTTON_BACK,
+ EV_HISTORY_ACTION_BUTTON_FORWARD
+} EvHistoryActionButton;
+
+G_DEFINE_TYPE (EvHistoryActionWidget, ev_history_action_widget, GTK_TYPE_TOOL_ITEM)
+
+static void
+ev_history_action_widget_finalize (GObject *object)
+{
+ EvHistoryActionWidget *control = EV_HISTORY_ACTION_WIDGET (object);
+
+ ev_history_action_widget_set_history (control, NULL);
+
+ G_OBJECT_CLASS (ev_history_action_widget_parent_class)->finalize (object);
+}
+
+static void
+ev_history_action_widget_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EvHistoryActionWidget *history_widget = EV_HISTORY_ACTION_WIDGET (object);
+
+ switch (prop_id) {
+ case PROP_POPUP_SHOWN:
+ g_value_set_boolean (value, history_widget->priv->popup_shown);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+ev_history_action_widget_set_popup_shown (EvHistoryActionWidget *history_widget,
+ gboolean popup_shown)
+{
+ if (history_widget->priv->popup_shown == popup_shown)
+ return;
+
+ history_widget->priv->popup_shown = popup_shown;
+ g_object_notify (G_OBJECT (history_widget), "popup-shown");
+}
+
+static void
+history_menu_link_activated (GtkMenuItem *item,
+ EvHistoryActionWidget *history_widget)
+{
+ EvLink *link;
+
+ link = EV_LINK (g_object_get_data (G_OBJECT (item), "ev-history-menu-item-link"));
+ if (!link)
+ return;
+
+ ev_history_go_to_link (history_widget->priv->history, link);
+}
+
+static void
+popup_menu_hide_cb (GtkMenu *menu,
+ EvHistoryActionWidget *history_widget)
+{
+ ev_history_action_widget_set_popup_shown (history_widget, FALSE);
+}
+
+static void
+ev_history_action_widget_show_popup (EvHistoryActionWidget *history_widget,
+ EvHistoryActionButton action_button,
+ guint button,
+ guint32 event_time)
+{
+ GtkWidget *menu;
+ GList *list = NULL;
+ GList *l;
+
+ switch (action_button) {
+ case EV_HISTORY_ACTION_BUTTON_BACK:
+ list = ev_history_get_back_list (history_widget->priv->history);
+ break;
+ case EV_HISTORY_ACTION_BUTTON_FORWARD:
+ list = ev_history_get_forward_list (history_widget->priv->history);
+ break;
+ }
+
+ if (!list)
+ return;
+
+ menu = gtk_menu_new ();
+
+ for (l = list; l; l = g_list_next (l)) {
+ EvLink *link = EV_LINK (l->data);
+ GtkWidget *item;
+
+ item = gtk_menu_item_new_with_label (ev_link_get_title (link));
+ g_object_set_data_full (G_OBJECT (item), "ev-history-menu-item-link",
+ g_object_ref (link), (GDestroyNotify)g_object_unref);
+ g_signal_connect_object (item, "activate",
+ G_CALLBACK (history_menu_link_activated),
+ history_widget, 0);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+ }
+
+ ev_history_action_widget_set_popup_shown (history_widget, TRUE);
+ g_signal_connect (menu, "hide",
+ G_CALLBACK (popup_menu_hide_cb),
+ history_widget);
+ gtk_menu_popup (GTK_MENU (menu),
+ NULL, NULL, NULL, NULL,
+ button, event_time);
+}
+
+static void
+button_clicked (GtkWidget *button,
+ EvHistoryActionWidget *history_widget)
+{
+ EvHistoryActionWidgetPrivate *priv = history_widget->priv;
+
+ if (button == priv->back_button)
+ ev_history_go_back (priv->history);
+ else if (button == priv->forward_button)
+ ev_history_go_forward (priv->history);
+}
+
+static gboolean
+button_pressed (GtkWidget *button,
+ GdkEventButton *event,
+ EvHistoryActionWidget *history_widget)
+{
+ EvHistoryActionWidgetPrivate *priv = history_widget->priv;
+
+ /* TODO: Show the popup menu after a long press too */
+ switch (event->button) {
+ case GDK_BUTTON_SECONDARY:
+ ev_history_action_widget_show_popup (history_widget,
+ button == priv->back_button ?
+ EV_HISTORY_ACTION_BUTTON_BACK :
+ EV_HISTORY_ACTION_BUTTON_FORWARD,
+ event->button, event->time);
+ return GDK_EVENT_STOP;
+ default:
+ break;
+ }
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+static gint
+get_icon_margin (EvHistoryActionWidget *history_widget)
+{
+ gint toolbar_size_px, menu_size_px;
+ GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (history_widget));
+
+ gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU, &menu_size_px, NULL);
+ gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_LARGE_TOOLBAR, &toolbar_size_px, NULL);
+
+ return (gint)floor ((toolbar_size_px - menu_size_px) / 2.0);
+}
+
+static GtkWidget *
+ev_history_action_widget_create_button (EvHistoryActionWidget *history_widget,
+ EvHistoryActionButton action_button)
+{
+ GtkWidget *button;
+ GtkWidget *image;
+ const gchar *icon_name = NULL;
+ const gchar *tooltip_text = NULL;
+
+ button = gtk_button_new ();
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (button_clicked),
+ history_widget);
+ g_signal_connect (button, "button-press-event",
+ G_CALLBACK (button_pressed),
+ history_widget);
+
+ switch (action_button) {
+ case EV_HISTORY_ACTION_BUTTON_BACK:
+ icon_name = "go-previous-symbolic";
+ tooltip_text = _("Go to previous history item");
+ break;
+ case EV_HISTORY_ACTION_BUTTON_FORWARD:
+ icon_name = "go-next-symbolic";
+ tooltip_text = _("Go to next history item");
+ break;
+ }
+
+ image = gtk_image_new ();
+ g_object_set (image, "margin", get_icon_margin (history_widget), NULL);
+ gtk_button_set_image (GTK_BUTTON (button), image);
+ gtk_image_set_from_icon_name (GTK_IMAGE (image), icon_name, GTK_ICON_SIZE_MENU);
+ gtk_widget_set_tooltip_text (button, tooltip_text);
+ gtk_widget_set_can_focus (button, FALSE);
+
+ return button;
+}
+
+static void
+ev_history_action_widget_init (EvHistoryActionWidget *history_widget)
+{
+ EvHistoryActionWidgetPrivate *priv;
+ GtkWidget *box;
+ GtkStyleContext *style_context;
+
+ history_widget->priv = G_TYPE_INSTANCE_GET_PRIVATE (history_widget, EV_TYPE_HISTORY_ACTION_WIDGET, EvHistoryActionWidgetPrivate);
+ priv = history_widget->priv;
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ style_context = gtk_widget_get_style_context (box);
+ gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_RAISED);
+ gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_LINKED);
+
+ priv->back_button = ev_history_action_widget_create_button (history_widget,
+ EV_HISTORY_ACTION_BUTTON_BACK);
+ gtk_container_add (GTK_CONTAINER (box), priv->back_button);
+ gtk_widget_show (priv->back_button);
+
+ priv->forward_button = ev_history_action_widget_create_button (history_widget,
+ EV_HISTORY_ACTION_BUTTON_FORWARD);
+ gtk_container_add (GTK_CONTAINER (box), priv->forward_button);
+ gtk_widget_show (priv->forward_button);
+
+ gtk_container_add (GTK_CONTAINER (history_widget), box);
+ gtk_widget_show (box);
+
+ gtk_widget_set_sensitive (priv->back_button, FALSE);
+ gtk_widget_set_sensitive (priv->forward_button, FALSE);
+}
+
+static void
+ev_history_action_widget_class_init (EvHistoryActionWidgetClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = ev_history_action_widget_get_property;
+ object_class->finalize = ev_history_action_widget_finalize;
+
+ g_object_class_install_property (object_class,
+ PROP_POPUP_SHOWN,
+ g_param_spec_boolean ("popup-shown",
+ "Popup shown",
+ "Whether the history's dropdown is shown",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_type_class_add_private (object_class, sizeof (EvHistoryActionWidgetPrivate));
+}
+
+static void
+history_changed_cb (EvHistory *history,
+ EvHistoryActionWidget *history_widget)
+{
+ EvHistoryActionWidgetPrivate *priv = history_widget->priv;
+
+ gtk_widget_set_sensitive (priv->back_button, ev_history_can_go_back (history));
+ gtk_widget_set_sensitive (priv->forward_button, ev_history_can_go_forward (history));
+}
+
+void
+ev_history_action_widget_set_history (EvHistoryActionWidget *history_widget,
+ EvHistory *history)
+{
+ g_return_if_fail (EV_IS_HISTORY_ACTION_WIDGET (history_widget));
+
+ if (history_widget->priv->history == history)
+ return;
+
+ if (history_widget->priv->history) {
+ g_object_remove_weak_pointer (G_OBJECT (history_widget->priv->history),
+ (gpointer)&history_widget->priv->history);
+ g_signal_handlers_disconnect_by_func (history_widget->priv->history,
+ G_CALLBACK (history_changed_cb),
+ history_widget);
+ }
+
+ history_widget->priv->history = history;
+ if (!history)
+ return;
+
+ g_object_add_weak_pointer (G_OBJECT (history),
+ (gpointer)&history_widget->priv->history);
+
+ g_signal_connect (history, "changed",
+ G_CALLBACK (history_changed_cb),
+ history_widget);
+}
+
diff --git a/shell/ev-history-action-widget.h b/shell/ev-history-action-widget.h
new file mode 100644
index 00000000..befa24b2
--- /dev/null
+++ b/shell/ev-history-action-widget.h
@@ -0,0 +1,58 @@
+/* ev-history-action-widget.h
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2013 Carlos Garcia Campos
+ *
+ * Evince 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.
+ *
+ * Evince 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.
+ */
+
+#ifndef EV_HISTORY_ACTION_WIDGET_H
+#define EV_HISTORY_ACTION_WIDGET_H
+
+#include
+
+#include "ev-history.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_HISTORY_ACTION_WIDGET (ev_history_action_widget_get_type())
+#define EV_HISTORY_ACTION_WIDGET(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_HISTORY_ACTION_WIDGET, EvHistoryActionWidget))
+#define EV_IS_HISTORY_ACTION_WIDGET(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_HISTORY_ACTION_WIDGET))
+#define EV_HISTORY_ACTION_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_HISTORY_ACTION_WIDGET, EvHistoryActionWidgetClass))
+#define EV_IS_HISTORY_ACTION_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_HISTORY_ACTION_WIDGET))
+#define EV_HISTORY_ACTION_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EV_TYPE_HISTORY_ACTION_WIDGET, EvHistoryActionWidgetClass))
+
+typedef struct _EvHistoryActionWidget EvHistoryActionWidget;
+typedef struct _EvHistoryActionWidgetClass EvHistoryActionWidgetClass;
+typedef struct _EvHistoryActionWidgetPrivate EvHistoryActionWidgetPrivate;
+
+struct _EvHistoryActionWidget {
+ GtkToolItem parent_object;
+
+ EvHistoryActionWidgetPrivate *priv;
+};
+
+struct _EvHistoryActionWidgetClass {
+ GtkToolItemClass parent_class;
+};
+
+GType ev_history_action_widget_get_type (void);
+
+void ev_history_action_widget_set_history (EvHistoryActionWidget *history_widget,
+ EvHistory *history);
+
+G_END_DECLS
+
+#endif
diff --git a/shell/ev-history-action.c b/shell/ev-history-action.c
new file mode 100644
index 00000000..cda9fc1f
--- /dev/null
+++ b/shell/ev-history-action.c
@@ -0,0 +1,119 @@
+/* ev-history-action.c
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2013 Carlos Garcia Campos
+ *
+ * Evince 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.
+ *
+ * Evince 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.
+ */
+
+#include "config.h"
+
+#include "ev-history-action.h"
+#include "ev-history-action-widget.h"
+
+enum {
+ ACTIVATED,
+ LAST_SIGNAL
+};
+
+
+struct _EvHistoryActionPrivate {
+ EvHistory *history;
+ gboolean popup_shown;
+};
+
+G_DEFINE_TYPE (EvHistoryAction, ev_history_action, GTK_TYPE_ACTION)
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+popup_shown_cb (GObject *history_widget,
+ GParamSpec *pspec,
+ EvHistoryAction *history_action)
+{
+ g_object_get (history_widget, "popup-shown", &history_action->priv->popup_shown, NULL);
+}
+
+static void
+connect_proxy (GtkAction *action,
+ GtkWidget *proxy)
+{
+ if (EV_IS_HISTORY_ACTION_WIDGET (proxy)) {
+ EvHistoryAction *history_action = EV_HISTORY_ACTION (action);
+ EvHistoryActionWidget *history_widget = EV_HISTORY_ACTION_WIDGET (proxy);
+
+ ev_history_action_widget_set_history (history_widget, history_action->priv->history);
+ g_signal_connect (history_widget, "notify::popup-shown",
+ G_CALLBACK (popup_shown_cb),
+ action);
+ }
+
+ GTK_ACTION_CLASS (ev_history_action_parent_class)->connect_proxy (action, proxy);
+}
+
+static void
+ev_history_action_class_init (EvHistoryActionClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkActionClass *action_class = GTK_ACTION_CLASS (class);
+
+ action_class->toolbar_item_type = EV_TYPE_HISTORY_ACTION_WIDGET;
+ action_class->connect_proxy = connect_proxy;
+
+ signals[ACTIVATED] =
+ g_signal_new ("activated",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_type_class_add_private (object_class, sizeof (EvHistoryActionPrivate));
+}
+
+static void
+ev_history_action_init (EvHistoryAction *action)
+{
+ action->priv = G_TYPE_INSTANCE_GET_PRIVATE (action, EV_TYPE_HISTORY_ACTION, EvHistoryActionPrivate);
+}
+
+void
+ev_history_action_set_history (EvHistoryAction *action,
+ EvHistory *history)
+{
+ GSList *proxies, *l;
+
+ g_return_if_fail (EV_IS_HISTORY_ACTION (action));
+ g_return_if_fail (EV_IS_HISTORY (history));
+
+ if (action->priv->history == history)
+ return;
+
+ action->priv->history = history;
+ proxies = gtk_action_get_proxies (GTK_ACTION (action));
+ for (l = proxies; l && l->data; l = g_slist_next (l)) {
+ if (EV_IS_HISTORY_ACTION_WIDGET (l->data))
+ ev_history_action_widget_set_history (EV_HISTORY_ACTION_WIDGET (l->data), history);
+ }
+}
+
+gboolean
+ev_history_action_get_popup_shown (EvHistoryAction *action)
+{
+ g_return_val_if_fail (EV_IS_HISTORY_ACTION (action), FALSE);
+
+ return action->priv->popup_shown;
+}
+
diff --git a/shell/ev-history-action.h b/shell/ev-history-action.h
new file mode 100644
index 00000000..48b3160a
--- /dev/null
+++ b/shell/ev-history-action.h
@@ -0,0 +1,59 @@
+/* ev-history-action.h
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2013 Carlos Garcia Campos
+ *
+ * Evince 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.
+ *
+ * Evince 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.
+ */
+
+#ifndef EV_HISTORY_ACTION_H
+#define EV_HISTORY_ACTION_H
+
+#include
+
+#include "ev-history.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_HISTORY_ACTION (ev_history_action_get_type ())
+#define EV_HISTORY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_HISTORY_ACTION, EvHistoryAction))
+#define EV_IS_HISTORY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_HISTORY_ACTION))
+#define EV_HISTORY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_HISTORY_ACTION, EvHistoryActionClass))
+#define EV_IS_HISTORY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EV_TYPE_HISTORY_ACTION))
+#define EV_HISTORY_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EV_TYPE_HISTORY_ACTION, EvHistoryActionClass))
+
+typedef struct _EvHistoryAction EvHistoryAction;
+typedef struct _EvHistoryActionClass EvHistoryActionClass;
+typedef struct _EvHistoryActionPrivate EvHistoryActionPrivate;
+
+struct _EvHistoryAction {
+ GtkAction parent;
+
+ EvHistoryActionPrivate *priv;
+};
+
+struct _EvHistoryActionClass {
+ GtkActionClass parent_class;
+};
+
+GType ev_history_action_get_type (void);
+
+void ev_history_action_set_history (EvHistoryAction *action,
+ EvHistory *history);
+gboolean ev_history_action_get_popup_shown (EvHistoryAction *action);
+
+G_END_DECLS
+
+#endif
diff --git a/shell/ev-history.c b/shell/ev-history.c
index 9b59014c..0f3ee2d1 100644
--- a/shell/ev-history.c
+++ b/shell/ev-history.c
@@ -24,40 +24,40 @@
#include "ev-history.h"
+enum {
+ CHANGED,
+ ACTIVATE_LINK,
-enum
-{
- HISTORY_CHANGED,
N_SIGNALS
};
static guint signals[N_SIGNALS] = {0, };
-struct _EvHistoryPrivate
-{
- GList *links;
-};
+struct _EvHistoryPrivate {
+ EvLink *current;
+ GList *back_list;
+ GList *forward_list;
-static void ev_history_init (EvHistory *history);
-static void ev_history_class_init (EvHistoryClass *class);
+ EvDocumentModel *model;
+ gulong page_changed_handler_id;
+ gboolean activating_current_link;
+};
G_DEFINE_TYPE (EvHistory, ev_history, G_TYPE_OBJECT)
-#define EV_HISTORY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_HISTORY, EvHistoryPrivate))
+static void ev_history_set_model (EvHistory *history,
+ EvDocumentModel *model);
static void
-ev_history_init (EvHistory *history)
+ev_history_clear (EvHistory *history)
{
- history->priv = EV_HISTORY_GET_PRIVATE (history);
+ g_clear_object (&history->priv->current);
- history->priv->links = NULL;
-}
+ g_list_free_full (history->priv->back_list, (GDestroyNotify)g_object_unref);
+ history->priv->back_list = NULL;
-static void
-free_links_list (GList *l)
-{
- g_list_foreach (l, (GFunc)g_object_unref, NULL);
- g_list_free (l);
+ g_list_free_full (history->priv->forward_list, (GDestroyNotify)g_object_unref);
+ history->priv->forward_list = NULL;
}
static void
@@ -65,7 +65,8 @@ ev_history_finalize (GObject *object)
{
EvHistory *history = EV_HISTORY (object);
- free_links_list (history->priv->links);
+ ev_history_clear (history);
+ ev_history_set_model (history, NULL);
G_OBJECT_CLASS (ev_history_parent_class)->finalize (object);
}
@@ -77,72 +78,347 @@ ev_history_class_init (EvHistoryClass *class)
object_class->finalize = ev_history_finalize;
- signals[HISTORY_CHANGED] =
- g_signal_new ("changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (EvHistoryClass, changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ signals[CHANGED] =
+ g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EvHistoryClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[ACTIVATE_LINK] =
+ g_signal_new ("activate-link",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EvHistoryClass, activate_link),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
g_type_class_add_private (object_class, sizeof (EvHistoryPrivate));
}
-#define HISTORY_LENGTH 7
+static void
+ev_history_init (EvHistory *history)
+{
+ history->priv = G_TYPE_INSTANCE_GET_PRIVATE (history, EV_TYPE_HISTORY, EvHistoryPrivate);
+}
void
-ev_history_add_link (EvHistory *history, EvLink *link)
+ev_history_add_link (EvHistory *history,
+ EvLink *link)
{
- GList *l;
-
g_return_if_fail (EV_IS_HISTORY (history));
g_return_if_fail (EV_IS_LINK (link));
- for (l = history->priv->links; l; l = l->next) {
- if (!strcmp (ev_link_get_title (EV_LINK (l->data)), ev_link_get_title (link))) {
- g_object_unref (G_OBJECT (l->data));
- history->priv->links = g_list_delete_link (history->priv->links, l);
- break;
- }
- }
+ if (history->priv->activating_current_link)
+ return;
+
+ if (ev_history_go_to_link (history, link))
+ return;
+
+ if (history->priv->current) {
+ history->priv->back_list = g_list_prepend (history->priv->back_list,
+ history->priv->current);
+ }
+
+ history->priv->current = g_object_ref (link);
+
+ g_list_free_full (history->priv->forward_list, (GDestroyNotify)g_object_unref);
+ history->priv->forward_list = NULL;
+
+ /* TODO: Decide a history limit and delete old links when the limit is reached */
+
+ g_signal_emit (history, signals[CHANGED], 0);
+}
+
+static void
+ev_history_activate_current_link (EvHistory *history)
+{
+ history->priv->activating_current_link = TRUE;
+ g_signal_handler_block (history->priv->model, history->priv->page_changed_handler_id);
+ g_signal_emit (history, signals[ACTIVATE_LINK], 0, history->priv->current);
+ g_signal_handler_unblock (history->priv->model, history->priv->page_changed_handler_id);
+ history->priv->activating_current_link = FALSE;
+
+ g_signal_emit (history, signals[CHANGED], 0);
+}
+
+gboolean
+ev_history_can_go_back (EvHistory *history)
+{
+ g_return_val_if_fail (EV_IS_HISTORY (history), FALSE);
- g_object_ref (link);
- history->priv->links = g_list_append (history->priv->links,
- link);
-
- if (g_list_length (history->priv->links) > HISTORY_LENGTH) {
- g_object_unref (G_OBJECT (history->priv->links->data));
- history->priv->links = g_list_delete_link (history->priv->links,
- history->priv->links);
- }
-
- g_signal_emit (history, signals[HISTORY_CHANGED], 0);
+ return history->priv->back_list != NULL;
}
-EvLink *
-ev_history_get_link_nth (EvHistory *history, int index)
+void
+ev_history_go_back (EvHistory *history)
{
- GList *l;
+ g_return_if_fail (EV_IS_HISTORY (history));
- g_return_val_if_fail (EV_IS_HISTORY (history), NULL);
+ if (!history->priv->current || !history->priv->back_list)
+ return;
- l = g_list_nth (history->priv->links, index);
+ history->priv->forward_list = g_list_prepend (history->priv->forward_list,
+ history->priv->current);
+ history->priv->current = EV_LINK (history->priv->back_list->data);
+ history->priv->back_list = g_list_delete_link (history->priv->back_list,
+ history->priv->back_list);
- return EV_LINK (l->data);
+ ev_history_activate_current_link (history);
}
-int
-ev_history_get_n_links (EvHistory *history)
+gboolean
+ev_history_can_go_forward (EvHistory *history)
{
- g_return_val_if_fail (EV_IS_HISTORY (history), -1);
+ g_return_val_if_fail (EV_IS_HISTORY (history), FALSE);
- return g_list_length (history->priv->links);
+ return history->priv->forward_list != NULL;
}
-EvHistory *
-ev_history_new (void)
+void
+ev_history_go_forward (EvHistory *history)
+{
+ g_return_if_fail (EV_IS_HISTORY (history));
+
+ if (!history->priv->current || !history->priv->forward_list)
+ return;
+
+ history->priv->back_list = g_list_prepend (history->priv->back_list,
+ history->priv->current);
+ history->priv->current = EV_LINK (history->priv->forward_list->data);
+ history->priv->forward_list = g_list_delete_link (history->priv->forward_list,
+ history->priv->forward_list);
+
+ ev_history_activate_current_link (history);
+}
+
+static gint
+compare_link (EvLink *a,
+ EvLink *b)
+{
+ if (a == b)
+ return 0;
+
+ return ev_link_action_equal (ev_link_get_action (a), ev_link_get_action (b)) ? 0 : 1;
+}
+
+gboolean
+ev_history_go_to_link (EvHistory *history,
+ EvLink *link)
{
- return EV_HISTORY (g_object_new (EV_TYPE_HISTORY, NULL));
+ GList *l;
+
+ g_return_val_if_fail (EV_IS_HISTORY (history), FALSE);
+ g_return_val_if_fail (EV_IS_LINK (link), FALSE);
+
+ if (!history->priv->current || (!history->priv->back_list && !history->priv->forward_list))
+ return FALSE;
+
+ l = g_list_find_custom (history->priv->back_list, link, (GCompareFunc)compare_link);
+ if (l) {
+ if (l->next)
+ l->next->prev = NULL;
+ if (l->prev)
+ l->prev->next = NULL;
+
+ history->priv->forward_list = g_list_prepend (history->priv->forward_list,
+ history->priv->current);
+ history->priv->forward_list = g_list_concat (g_list_reverse (history->priv->back_list),
+ history->priv->forward_list);
+ history->priv->back_list = l->next;
+ history->priv->current = EV_LINK (l->data);
+ g_list_free_1 (l);
+
+ ev_history_activate_current_link (history);
+
+ return TRUE;
+ }
+
+ l = g_list_find_custom (history->priv->forward_list, link, (GCompareFunc)compare_link);
+ if (l) {
+ if (l->next)
+ l->next->prev = NULL;
+ if (l->prev)
+ l->prev->next = NULL;
+
+ history->priv->back_list = g_list_prepend (history->priv->back_list,
+ history->priv->current);
+ history->priv->back_list = g_list_concat (g_list_reverse (history->priv->forward_list),
+ history->priv->back_list);
+ history->priv->forward_list = l->next;
+ history->priv->current = EV_LINK (l->data);
+ g_list_free_1 (l);
+
+ ev_history_activate_current_link (history);
+
+ return TRUE;
+ }
+
+ return FALSE;
}
+GList *
+ev_history_get_back_list (EvHistory *history)
+{
+ g_return_val_if_fail (EV_IS_HISTORY (history), NULL);
+
+ return history->priv->back_list;
+}
+
+GList *
+ev_history_get_forward_list (EvHistory *history)
+{
+ g_return_val_if_fail (EV_IS_HISTORY (history), NULL);
+
+ return history->priv->forward_list;
+}
+
+static gint
+ev_history_get_current_page (EvHistory *history)
+{
+ EvDocument *document;
+ EvLinkDest *dest;
+ EvLinkAction *action;
+
+ if (!history->priv->current)
+ return -1;
+
+ action = ev_link_get_action (history->priv->current);
+ if (!action)
+ return -1;
+
+ dest = ev_link_action_get_dest (action);
+ if (!dest)
+ return -1;
+
+ switch (ev_link_dest_get_dest_type (dest)) {
+ case EV_LINK_DEST_TYPE_NAMED:
+ document = ev_document_model_get_document (history->priv->model);
+ if (!EV_IS_DOCUMENT_LINKS (document))
+ return -1;
+
+ return ev_document_links_find_link_page (EV_DOCUMENT_LINKS (document),
+ ev_link_dest_get_named_dest (dest));
+ case EV_LINK_DEST_TYPE_PAGE_LABEL: {
+ gint page = -1;
+
+ document = ev_document_model_get_document (history->priv->model);
+ ev_document_find_page_by_label (document,
+ ev_link_dest_get_page_label (dest),
+ &page);
+
+ return page;
+ }
+ default:
+ return ev_link_dest_get_page (dest);
+ }
+
+ return -1;
+}
+
+static void
+ev_history_add_link_for_page (EvHistory *history,
+ gint page)
+{
+ EvDocument *document;
+ EvLinkDest *dest;
+ EvLinkAction *action;
+ EvLink *link;
+ gchar *page_label;
+ gchar *title;
+
+ if (ev_history_get_current_page (history) == page)
+ return;
+
+ document = ev_document_model_get_document (history->priv->model);
+ if (!document)
+ return;
+
+ page_label = ev_document_get_page_label (document, page);
+ if (!page_label)
+ return;
+
+ title = g_strdup_printf (_("Page %s"), page_label);
+ g_free (page_label);
+
+ dest = ev_link_dest_new_page (page);
+ action = ev_link_action_new_dest (dest);
+ g_object_unref (dest);
+
+ link = ev_link_new (title, action);
+ g_object_unref (action);
+ g_free (title);
+
+ ev_history_add_link (history, link);
+ g_object_unref (link);
+}
+
+static void
+page_changed_cb (EvDocumentModel *model,
+ gint old_page,
+ gint new_page,
+ EvHistory *history)
+{
+ if (ABS (new_page - old_page) > 1)
+ ev_history_add_link_for_page (history, new_page);
+}
+
+static void
+document_changed_cb (EvDocumentModel *model,
+ GParamSpec *pspec,
+ EvHistory *history)
+{
+ ev_history_clear (history);
+ ev_history_add_link_for_page (history, ev_document_model_get_page (model));
+}
+
+static void
+ev_history_set_model (EvHistory *history,
+ EvDocumentModel *model)
+{
+ if (history->priv->model == model)
+ return;
+
+ if (history->priv->model) {
+ g_object_remove_weak_pointer (G_OBJECT (history->priv->model),
+ (gpointer)&history->priv->model);
+
+ if (history->priv->page_changed_handler_id) {
+ g_signal_handler_disconnect (history->priv->model,
+ history->priv->page_changed_handler_id);
+ history->priv->page_changed_handler_id = 0;
+ }
+ }
+
+ history->priv->model = model;
+ if (!model)
+ return;
+
+ g_object_add_weak_pointer (G_OBJECT (model),
+ (gpointer)&history->priv->model);
+
+ g_signal_connect (history->priv->model, "notify::document",
+ G_CALLBACK (document_changed_cb),
+ history);
+ history->priv->page_changed_handler_id =
+ g_signal_connect (history->priv->model, "page-changed",
+ G_CALLBACK (page_changed_cb),
+ history);
+}
+
+EvHistory *
+ev_history_new (EvDocumentModel *model)
+{
+ EvHistory *history;
+
+ g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), NULL);
+
+ history = EV_HISTORY (g_object_new (EV_TYPE_HISTORY, NULL));
+ ev_history_set_model (history, model);
+
+ return history;
+}
diff --git a/shell/ev-history.h b/shell/ev-history.h
index d8bb53f5..02604c79 100644
--- a/shell/ev-history.h
+++ b/shell/ev-history.h
@@ -21,8 +21,8 @@
#define EV_HISTORY_H
#include
-
-#include "ev-link.h"
+#include
+#include
G_BEGIN_DECLS
@@ -40,7 +40,7 @@ typedef struct _EvHistoryClass EvHistoryClass;
struct _EvHistory
{
GObject parent;
-
+
/*< private >*/
EvHistoryPrivate *priv;
};
@@ -48,17 +48,24 @@ struct _EvHistory
struct _EvHistoryClass
{
GObjectClass parent_class;
-
- void (*changed) (EvHistory *history);
+
+ void (* changed) (EvHistory *history);
+ void (* activate_link) (EvHistory *history,
+ EvLink *link);
};
-GType ev_history_get_type (void);
-EvHistory *ev_history_new (void);
-void ev_history_add_link (EvHistory *history,
- EvLink *linkk);
-EvLink *ev_history_get_link_nth (EvHistory *history,
- int index);
-int ev_history_get_n_links (EvHistory *history);
+GType ev_history_get_type (void);
+EvHistory *ev_history_new (EvDocumentModel *model);
+void ev_history_add_link (EvHistory *history,
+ EvLink *link);
+gboolean ev_history_can_go_back (EvHistory *history);
+void ev_history_go_back (EvHistory *history);
+gboolean ev_history_can_go_forward (EvHistory *history);
+void ev_history_go_forward (EvHistory *history);
+gboolean ev_history_go_to_link (EvHistory *history,
+ EvLink *link);
+GList *ev_history_get_back_list (EvHistory *history);
+GList *ev_history_get_forward_list (EvHistory *history);
G_END_DECLS
diff --git a/shell/ev-navigation-action-widget.c b/shell/ev-navigation-action-widget.c
deleted file mode 100644
index c3de6958..00000000
--- a/shell/ev-navigation-action-widget.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2003, 2004 Marco Pesenti Gritti
- * Copyright (C) 2003, 2004 Christian Persch
- *
- * 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "ev-navigation-action-widget.h"
-
-#include
-#include
-
-static void ev_navigation_action_widget_init (EvNavigationActionWidget *action_widget);
-static void ev_navigation_action_widget_class_init (EvNavigationActionWidgetClass *action_widget);
-static void ev_navigation_action_widget_toggled (GtkToggleToolButton *toggle);
-static gboolean ev_navigation_action_widget_button_press_event (GtkWidget *widget,
- GdkEventButton *event,
- gpointer data);
-
-G_DEFINE_TYPE (EvNavigationActionWidget, ev_navigation_action_widget, GTK_TYPE_TOGGLE_TOOL_BUTTON)
-
-enum
-{
- SHOW_MENU,
- LAST_SIGNAL
-};
-
-static gint signals[LAST_SIGNAL];
-
-static void
-ev_navigation_action_widget_init (EvNavigationActionWidget *action_widget)
-{
- GtkWidget *toggle_button;
-
- /* It's rather dirty hack but we need a child to connect to
- * button press event
- */
-
- toggle_button = gtk_bin_get_child (GTK_BIN (action_widget));
-
- g_signal_connect (toggle_button, "button-press-event",
- G_CALLBACK (ev_navigation_action_widget_button_press_event),
- action_widget);
- return;
-}
-
-static void
-ev_navigation_action_widget_class_init (EvNavigationActionWidgetClass *klass)
-{
- GtkToggleToolButtonClass *toggle_tool_button_class = GTK_TOGGLE_TOOL_BUTTON_CLASS (klass);
-
- toggle_tool_button_class->toggled = ev_navigation_action_widget_toggled;
-
- signals[SHOW_MENU] =
- g_signal_new ("show-menu",
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EvNavigationActionWidgetClass, show_menu),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-static int
-menu_deactivate_cb (GtkMenuShell *menu_shell,
- EvNavigationActionWidget *widget)
-{
- gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (widget), FALSE);
- return TRUE;
-}
-
-static void
-menu_detacher (GtkWidget *widget,
- GtkMenu *menu)
-{
- EvNavigationActionWidget *button = EV_NAVIGATION_ACTION_WIDGET (widget);
- g_return_if_fail (button->menu == menu);
- button->menu = NULL;
-}
-
-void
-ev_navigation_action_widget_set_menu(EvNavigationActionWidget *button, GtkWidget *menu)
-{
-
- if (button->menu == GTK_MENU (menu))
- return;
-
- if (button->menu && gtk_widget_get_visible (GTK_WIDGET (button->menu)))
- gtk_menu_shell_deactivate (GTK_MENU_SHELL (button->menu));
-
- if (button->menu) {
- g_signal_handlers_disconnect_by_func (button->menu,
- menu_deactivate_cb,
- button);
- gtk_menu_detach (button->menu);
- }
-
- button->menu = GTK_MENU (menu);
-
- if (button->menu) {
- gtk_menu_attach_to_widget (button->menu, GTK_WIDGET (button),
- menu_detacher);
- g_signal_connect (button->menu, "deactivate",
- G_CALLBACK (menu_deactivate_cb), button);
- }
-}
-
-static void
-menu_position_func (GtkMenu *menu,
- int *x,
- int *y,
- gboolean *push_in,
- EvNavigationActionWidget *button)
-{
- GtkWidget *widget = GTK_WIDGET (button);
- GtkRequisition menu_req;
- GtkAllocation allocation;
- GtkTextDirection direction;
- GdkWindow *gdk_window;
- GdkRectangle monitor;
- gint monitor_num;
- GdkScreen *screen;
-
- gtk_widget_get_preferred_size (GTK_WIDGET (button->menu), &menu_req, NULL);
- direction = gtk_widget_get_direction (widget);
- screen = gtk_widget_get_screen (GTK_WIDGET (menu));
-
- gdk_window = gtk_widget_get_window (widget);
- monitor_num = gdk_screen_get_monitor_at_window (screen, gdk_window);
- if (monitor_num < 0)
- monitor_num = 0;
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
-
- gdk_window_get_origin (gdk_window, x, y);
- gtk_widget_get_allocation (widget, &allocation);
- *x += allocation.x;
- *y += allocation.y;
-
- if (direction == GTK_TEXT_DIR_LTR)
- *x += MAX (allocation.width - menu_req.width, 0);
- else if (menu_req.width > allocation.width)
- *x -= menu_req.width - allocation.width;
-
- if ((*y + allocation.height + menu_req.height) <= monitor.y + monitor.height)
- *y += allocation.height;
- else if ((*y - menu_req.height) >= monitor.y)
- *y -= menu_req.height;
- else if (monitor.y + monitor.height - (*y + allocation.height) > *y)
- *y += allocation.height;
- else
- *y -= menu_req.height;
-
- *push_in = FALSE;
-}
-
-static void
-popup_menu_under_arrow (EvNavigationActionWidget *button,
- GdkEventButton *event)
-{
- g_signal_emit (button, signals[SHOW_MENU], 0);
-
- if (!button->menu)
- return;
-
- gtk_menu_popup (button->menu, NULL, NULL,
- (GtkMenuPositionFunc) menu_position_func,
- button,
- event ? event->button : 0,
- event ? event->time : gtk_get_current_event_time ());
-}
-
-static void
-ev_navigation_action_widget_toggled (GtkToggleToolButton *toggle)
-{
- EvNavigationActionWidget *button = EV_NAVIGATION_ACTION_WIDGET (toggle);
- if (!button->menu)
- return;
-
- if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (button)) &&
- !gtk_widget_get_visible (GTK_WIDGET (button->menu))) {
- /* we get here only when the menu is activated by a key
- * press, so that we can select the first menu item */
- popup_menu_under_arrow (button, NULL);
- gtk_menu_shell_select_first (GTK_MENU_SHELL (button->menu), FALSE);
- }
-}
-
-static gboolean
-ev_navigation_action_widget_button_press_event (GtkWidget *widget,
- GdkEventButton *event,
- gpointer data)
-{
- EvNavigationActionWidget *button = EV_NAVIGATION_ACTION_WIDGET (data);
-
- if (event->button == 1) {
- popup_menu_under_arrow (button, event);
- gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (button), TRUE);
- return TRUE;
- }
- return FALSE;
-}
diff --git a/shell/ev-navigation-action-widget.h b/shell/ev-navigation-action-widget.h
deleted file mode 100644
index 4241cd31..00000000
--- a/shell/ev-navigation-action-widget.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2003, 2004 Marco Pesenti Gritti
- * Copyright (C) 2003, 2004 Christian Persch
- *
- * 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include
-
-#define EV_TYPE_NAVIGATION_ACTION_WIDGET (ev_navigation_action_widget_get_type ())
-#define EV_NAVIGATION_ACTION_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_NAVIGATION_ACTION_WIDGET, EvNavigationActionWidget))
-
-typedef struct _EvNavigationActionWidget EvNavigationActionWidget;
-typedef struct _EvNavigationActionWidgetClass EvNavigationActionWidgetClass;
-
-struct _EvNavigationActionWidget
-{
- GtkToggleToolButton parent;
-
- GtkMenu *menu;
-};
-
-struct _EvNavigationActionWidgetClass
-{
- GtkToggleToolButtonClass parent_class;
-
- void (*show_menu) (EvNavigationActionWidget *widget);
-};
-
-GType ev_navigation_action_widget_get_type (void);
-
-void
-ev_navigation_action_widget_set_menu(EvNavigationActionWidget *widget, GtkWidget *menu);
diff --git a/shell/ev-navigation-action.c b/shell/ev-navigation-action.c
deleted file mode 100644
index b34c3789..00000000
--- a/shell/ev-navigation-action.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2003, 2004 Marco Pesenti Gritti
- * Copyright (C) 2003, 2004 Christian Persch
- *
- * 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-
-#include
-#include
-
-#include "ev-navigation-action.h"
-#include "ev-navigation-action-widget.h"
-
-
-enum
-{
- WIDGET_ACTIVATE_LINK,
- WIDGET_N_SIGNALS
-};
-
-static guint widget_signals[WIDGET_N_SIGNALS] = {0, };
-
-struct _EvNavigationActionPrivate
-{
- EvHistory *history;
-};
-
-static void ev_navigation_action_init (EvNavigationAction *action);
-static void ev_navigation_action_class_init (EvNavigationActionClass *class);
-
-G_DEFINE_TYPE (EvNavigationAction, ev_navigation_action, GTK_TYPE_ACTION)
-
-#define MAX_LABEL_LENGTH 48
-
-#define EV_NAVIGATION_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_NAVIGATION_ACTION, EvNavigationActionPrivate))
-
-static void
-ev_navigation_action_history_changed (EvHistory *history,
- gpointer data)
-{
- EvNavigationAction *action = EV_NAVIGATION_ACTION (data);
-
- gtk_action_set_sensitive (GTK_ACTION (action),
- ev_history_get_n_links (history) > 0);
-}
-
-void
-ev_navigation_action_set_history (EvNavigationAction *action,
- EvHistory *history)
-{
- action->priv->history = history;
-
- g_object_add_weak_pointer (G_OBJECT (action->priv->history),
- (gpointer) &action->priv->history);
-
- g_signal_connect_object (history, "changed",
- G_CALLBACK (ev_navigation_action_history_changed),
- action, 0);
-}
-
-static void
-activate_menu_item_cb (GtkWidget *widget, EvNavigationAction *action)
-{
- int index;
-
- g_return_if_fail (EV_IS_HISTORY (action->priv->history));
-
- index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "index"));
-
- if (action->priv->history) {
- EvLink *link;
-
- link = ev_history_get_link_nth (action->priv->history, index);
-
- g_signal_emit (action, widget_signals[WIDGET_ACTIVATE_LINK], 0, link);
- }
-}
-
-static GtkWidget *
-new_history_menu_item (EvNavigationAction *action,
- EvLink *link,
- int index)
-{
- GtkLabel *label;
- GtkWidget *item;
- const char *title;
-
- title = ev_link_get_title (link);
- item = gtk_image_menu_item_new_with_label (title);
- label = GTK_LABEL (gtk_bin_get_child (GTK_BIN (item)));
- gtk_label_set_use_markup (label, TRUE);
- g_object_set_data (G_OBJECT (item), "index",
- GINT_TO_POINTER (index));
-
- gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END);
- gtk_label_set_max_width_chars (label, MAX_LABEL_LENGTH);
-
- g_signal_connect (item, "activate",
- G_CALLBACK (activate_menu_item_cb),
- action);
-
- gtk_widget_show (item);
-
- return item;
-}
-
-static GtkWidget *
-build_menu (EvNavigationAction *action)
-{
- GtkMenuShell *menu;
- GtkWidget *item;
- EvLink *link;
- EvHistory *history = action->priv->history;
- int start, end, i;
-
- if (history == NULL || ev_history_get_n_links (history) <= 0) {
- return NULL;
- }
-
- menu = GTK_MENU_SHELL (gtk_menu_new ());
-
- start = 0;
- end = ev_history_get_n_links (history);
-
- for (i = start; i < end; i++) {
- link = ev_history_get_link_nth (history, i);
- item = new_history_menu_item (action, link, i);
- gtk_menu_shell_prepend (menu, item);
- }
-
- return GTK_WIDGET (menu);
-}
-
-static void
-menu_activated_cb (EvNavigationActionWidget *button,
- EvNavigationAction *action)
-{
- GtkWidget *menu;
-
- menu = build_menu (action);
- ev_navigation_action_widget_set_menu (button, menu);
-}
-
-static void
-connect_proxy (GtkAction *action, GtkWidget *proxy)
-{
- GtkWidget *menu;
-
- if (GTK_IS_TOOL_ITEM (proxy)) {
- /* set dummy menu so the arrow gets sensitive */
- menu = gtk_menu_new ();
- ev_navigation_action_widget_set_menu (EV_NAVIGATION_ACTION_WIDGET (proxy), menu);
-
- g_signal_connect (proxy, "show-menu",
- G_CALLBACK (menu_activated_cb), action);
- }
-
- GTK_ACTION_CLASS (ev_navigation_action_parent_class)->connect_proxy (action, proxy);
-}
-
-static GtkWidget *
-create_tool_item (GtkAction *action)
-{
- EvNavigationActionWidget *proxy;
-
- proxy = g_object_new (EV_TYPE_NAVIGATION_ACTION_WIDGET, NULL);
- gtk_widget_show (GTK_WIDGET (proxy));
-
- return GTK_WIDGET (proxy);
-}
-
-static GtkWidget *
-create_menu_item (GtkAction *action)
-{
- GtkWidget *menu;
- GtkWidget *menu_item;
-
- menu = build_menu (EV_NAVIGATION_ACTION (action));
-
- menu_item = GTK_ACTION_CLASS (ev_navigation_action_parent_class)->create_menu_item (action);
-
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
-
- gtk_widget_show (menu_item);
-
- return menu_item;
-}
-
-static void
-ev_navigation_action_init (EvNavigationAction *action)
-{
- action->priv = EV_NAVIGATION_ACTION_GET_PRIVATE (action);
-}
-
-static void
-ev_navigation_action_finalize (GObject *object)
-{
- EvNavigationAction *action = EV_NAVIGATION_ACTION (object);
-
- if (action->priv->history) {
- g_object_remove_weak_pointer (G_OBJECT (action->priv->history),
- (gpointer) &action->priv->history);
- action->priv->history = NULL;
- }
-
- G_OBJECT_CLASS (ev_navigation_action_parent_class)->finalize (object);
-}
-
-static void
-ev_navigation_action_class_init (EvNavigationActionClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- GtkActionClass *action_class = GTK_ACTION_CLASS (class);
-
- object_class->finalize = ev_navigation_action_finalize;
-
- action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM;
- action_class->create_tool_item = create_tool_item;
- action_class->connect_proxy = connect_proxy;
- action_class->create_menu_item = create_menu_item;
-
- widget_signals[WIDGET_ACTIVATE_LINK] = g_signal_new ("activate_link",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (EvNavigationActionClass, activate_link),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
-
- g_type_class_add_private (object_class, sizeof (EvNavigationActionPrivate));
-}
diff --git a/shell/ev-navigation-action.h b/shell/ev-navigation-action.h
deleted file mode 100644
index 8089e4f4..00000000
--- a/shell/ev-navigation-action.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2003, 2004 Marco Pesenti Gritti
- * Copyright (C) 2003, 2004 Christian Persch
- *
- * 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef EV_NAVIGATION_ACTION_H
-#define EV_NAVIGATION_ACTION_H
-
-#include
-
-#include "ev-history.h"
-#include "ev-link.h"
-
-G_BEGIN_DECLS
-
-#define EV_TYPE_NAVIGATION_ACTION (ev_navigation_action_get_type ())
-#define EV_NAVIGATION_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_NAVIGATION_ACTION, EvNavigationAction))
-#define EV_NAVIGATION_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_NAVIGATION_ACTION, EvNavigationActionClass))
-#define EV_IS_NAVIGATION_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_NAVIGATION_ACTION))
-#define EV_IS_NAVIGATION_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EV_TYPE_NAVIGATION_ACTION))
-#define EV_NAVIGATION_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EV_TYPE_NAVIGATION_ACTION, EvNavigationActionClass))
-
-typedef struct _EvNavigationAction EvNavigationAction;
-typedef struct _EvNavigationActionPrivate EvNavigationActionPrivate;
-typedef struct _EvNavigationActionClass EvNavigationActionClass;
-
-struct _EvNavigationAction
-{
- GtkAction parent;
-
- /*< private >*/
- EvNavigationActionPrivate *priv;
-};
-
-struct _EvNavigationActionClass
-{
- GtkActionClass parent_class;
-
- void (* activate_link) (EvNavigationAction *action,
- EvLink *link);
-};
-
-GType ev_navigation_action_get_type (void);
-void ev_navigation_action_set_history (EvNavigationAction *action,
- EvHistory *history);
-
-G_END_DECLS
-
-#endif
diff --git a/shell/ev-toolbar.c b/shell/ev-toolbar.c
index 20d3acaa..a408769b 100644
--- a/shell/ev-toolbar.c
+++ b/shell/ev-toolbar.c
@@ -26,6 +26,7 @@
#include "ev-stock-icons.h"
#include "ev-zoom-action.h"
+#include "ev-history-action.h"
#include
enum
@@ -203,6 +204,13 @@ ev_toolbar_constructed (GObject *object)
gtk_container_add (GTK_CONTAINER (ev_toolbar), tool_item);
gtk_widget_show (tool_item);
+ /* History */
+ action = gtk_action_group_get_action (action_group, "History");
+ tool_item = gtk_action_create_tool_item (action);
+ gtk_widget_set_margin_right (tool_item, 12);
+ gtk_container_add (GTK_CONTAINER (ev_toolbar), tool_item);
+ gtk_widget_show (tool_item);
+
/* Zoom selector */
action = gtk_action_group_get_action (action_group, "ViewZoom");
tool_item = gtk_action_create_tool_item (action);
@@ -314,6 +322,10 @@ ev_toolbar_has_visible_popups (EvToolbar *ev_toolbar)
if (ev_zoom_action_get_popup_shown (EV_ZOOM_ACTION (action)))
return TRUE;
+ action = gtk_action_group_get_action (action_group, "History");
+ if (ev_history_action_get_popup_shown (EV_HISTORY_ACTION (action)))
+ return TRUE;
+
return FALSE;
}
diff --git a/shell/ev-window.c b/shell/ev-window.c
index 009a67e0..2a3e67df 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -62,9 +62,9 @@
#include "ev-loading-message.h"
#include "ev-message-area.h"
#include "ev-metadata.h"
-#include "ev-navigation-action.h"
#include "ev-open-recent-action.h"
#include "ev-page-action.h"
+#include "ev-history-action.h"
#include "ev-password-view.h"
#include "ev-properties-dialog.h"
#include "ev-sidebar-annotations.h"
@@ -237,7 +237,7 @@ struct _EvWindowPrivate {
#define PAGE_SELECTOR_ACTION "PageSelector"
#define ZOOM_CONTROL_ACTION "ViewZoom"
-#define NAVIGATION_ACTION "Navigation"
+#define HISTORY_ACTION "History"
#define GS_LOCKDOWN_SCHEMA_NAME "org.gnome.desktop.lockdown"
#define GS_LOCKDOWN_SAVE "disable-save-to-disk"
@@ -481,7 +481,6 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window)
/* Toolbar-specific actions: */
ev_window_set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages);
ev_window_set_action_sensitive (ev_window, ZOOM_CONTROL_ACTION, has_pages);
- ev_window_set_action_sensitive (ev_window, NAVIGATION_ACTION, FALSE);
ev_window_update_actions_sensitivity (ev_window);
}
@@ -801,122 +800,98 @@ ev_window_hide_loading_message (EvWindow *window)
gtk_widget_hide (window->priv->loading_message);
}
-typedef struct _PageTitleData {
- const gchar *page_label;
- gchar *page_title;
-} PageTitleData;
+typedef struct _LinkTitleData {
+ EvLink *link;
+ const gchar *link_title;
+} LinkTitleData;
static gboolean
-ev_window_find_page_title (GtkTreeModel *tree_model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- PageTitleData *data)
+find_link_cb (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ LinkTitleData *data)
{
- gchar *page_string;
-
+ EvLink *link;
+ gboolean retval = FALSE;
+
gtk_tree_model_get (tree_model, iter,
- EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, &page_string,
+ EV_DOCUMENT_LINKS_COLUMN_LINK, &link,
-1);
-
- if (!page_string)
- return FALSE;
-
- if (!strcmp (page_string, data->page_label)) {
- gtk_tree_model_get (tree_model, iter,
- EV_DOCUMENT_LINKS_COLUMN_MARKUP, &data->page_title,
- -1);
- g_free (page_string);
- return TRUE;
+ if (!link)
+ return retval;
+
+ if (ev_link_action_equal (ev_link_get_action (data->link), ev_link_get_action (link))) {
+ data->link_title = ev_link_get_title (link);
+ retval = TRUE;
}
-
- g_free (page_string);
- return FALSE;
+
+ g_object_unref (link);
+
+ return retval;
}
-static gchar *
-ev_window_get_page_title (EvWindow *window,
- const gchar *page_label)
+static const gchar *
+ev_window_find_title_for_link (EvWindow *window,
+ EvLink *link)
{
if (EV_IS_DOCUMENT_LINKS (window->priv->document) &&
ev_document_links_has_document_links (EV_DOCUMENT_LINKS (window->priv->document))) {
- PageTitleData data;
+ LinkTitleData data;
GtkTreeModel *model;
- data.page_label = page_label;
- data.page_title = NULL;
+ data.link = link;
+ data.link_title = NULL;
g_object_get (G_OBJECT (window->priv->sidebar_links),
"model", &model,
NULL);
if (model) {
gtk_tree_model_foreach (model,
- (GtkTreeModelForeachFunc)ev_window_find_page_title,
+ (GtkTreeModelForeachFunc)find_link_cb,
&data);
g_object_unref (model);
}
- return data.page_title;
+ return data.link_title;
}
return NULL;
}
static void
-ev_window_add_history (EvWindow *window, gint page, EvLink *link)
+view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window)
{
- gchar *page_label = NULL;
- gchar *page_title;
- gchar *link_title;
- EvLink *real_link;
- EvLinkAction *action;
- EvLinkDest *dest;
-
- if (window->priv->history == NULL)
- return;
+ EvLink *new_link = NULL;
- if (!EV_IS_DOCUMENT_LINKS (window->priv->document))
- return;
-
- if (link) {
- action = g_object_ref (ev_link_get_action (link));
- dest = ev_link_action_get_dest (action);
- page_label = ev_document_links_get_dest_page_label (EV_DOCUMENT_LINKS (window->priv->document), dest);
- } else {
- dest = ev_link_dest_new_page (page);
- action = ev_link_action_new_dest (dest);
- g_object_unref (dest);
- page_label = ev_document_get_page_label (window->priv->document, page);
- }
+ if (!ev_link_get_title (link)) {
+ const gchar *link_title;
- if (!page_label)
- return;
-
- page_title = ev_window_get_page_title (window, page_label);
- if (page_title) {
- link_title = g_strdup_printf (_("Page %s — %s"), page_label, page_title);
- g_free (page_title);
- } else {
- link_title = g_strdup_printf (_("Page %s"), page_label);
- }
+ link_title = ev_window_find_title_for_link (window, link);
+ if (link_title) {
+ new_link = ev_link_new (link_title, ev_link_get_action (link));
+ } else {
+ EvLinkAction *action;
+ EvLinkDest *dest;
+ gchar *page_label;
+ gchar *title;
- real_link = ev_link_new (link_title, action);
- g_object_unref (action);
+ action = ev_link_get_action (link);
+ dest = ev_link_action_get_dest (action);
+ page_label = ev_document_links_get_dest_page_label (EV_DOCUMENT_LINKS (window->priv->document), dest);
+ if (!page_label)
+ return;
- ev_history_add_link (window->priv->history, real_link);
+ title = g_strdup_printf (_("Page %s"), page_label);
+ g_free (page_label);
- g_free (link_title);
- g_free (page_label);
- g_object_unref (real_link);
-}
-
-static void
-view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window)
-{
- int current_page = ev_document_model_get_page (window->priv->model);
-
- ev_window_add_history (window, 0, link);
- ev_window_add_history (window, current_page, NULL);
+ new_link = ev_link_new (title, action);
+ g_free (title);
+ }
+ }
+ ev_history_add_link (window->priv->history, new_link ? new_link : link);
+ if (new_link)
+ g_object_unref (new_link);
}
static void
@@ -955,11 +930,6 @@ ev_window_page_changed_cb (EvWindow *ev_window,
ev_window_update_find_status_message (ev_window);
- if (abs (new_page - old_page) > 1) {
- ev_window_add_history (ev_window, new_page, NULL);
- ev_window_add_history (ev_window, old_page, NULL);
- }
-
if (ev_window->priv->metadata && !ev_window_is_empty (ev_window))
ev_metadata_set_int (ev_window->priv->metadata, "page", new_page);
}
@@ -1437,7 +1407,6 @@ ev_window_setup_document (EvWindow *ev_window)
{
const EvDocumentInfo *info;
EvDocument *document = ev_window->priv->document;
- GtkAction *action;
ev_window->priv->setup_document_idle = 0;
@@ -1461,12 +1430,6 @@ ev_window_setup_document (EvWindow *ev_window)
ev_window_setup_action_sensitivity (ev_window);
- if (ev_window->priv->history)
- g_object_unref (ev_window->priv->history);
- ev_window->priv->history = ev_history_new ();
- action = gtk_action_group_get_action (ev_window->priv->action_group, NAVIGATION_ACTION);
- ev_navigation_action_set_history (EV_NAVIGATION_ACTION (action), ev_window->priv->history);
-
if (ev_window->priv->properties) {
ev_properties_dialog_set_document (EV_PROPERTIES_DIALOG (ev_window->priv->properties),
ev_window->priv->uri,
@@ -6072,17 +6035,12 @@ register_custom_actions (EvWindow *window, GtkActionGroup *group)
gtk_action_group_add_action (group, action);
g_object_unref (action);
- action = g_object_new (EV_TYPE_NAVIGATION_ACTION,
- "name", NAVIGATION_ACTION,
- "label", _("Navigation"),
- "is_important", TRUE,
- "short_label", _("Back"),
- "stock_id", GTK_STOCK_GO_BACK,
- /*translators: this is the history action*/
- "tooltip", _("Move across visited pages"),
+ action = g_object_new (EV_TYPE_HISTORY_ACTION,
+ "name", HISTORY_ACTION,
+ "label", _("History"),
NULL);
- g_signal_connect (action, "activate_link",
- G_CALLBACK (navigation_action_activate_link_cb), window);
+ ev_history_action_set_history (EV_HISTORY_ACTION (action),
+ window->priv->history);
gtk_action_group_add_action (group, action);
g_object_unref (action);
@@ -7082,6 +7040,11 @@ ev_window_init (EvWindow *ev_window)
ev_window->priv->presentation_mode_inhibit_id = 0;
ev_window->priv->title = ev_window_title_new (ev_window);
+ ev_window->priv->history = ev_history_new (ev_window->priv->model);
+ g_signal_connect (ev_window->priv->history, "activate-link",
+ G_CALLBACK (activate_link_cb),
+ ev_window);
+
ev_window->priv->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (ev_window), ev_window->priv->main_box);
gtk_widget_show (ev_window->priv->main_box);