aboutsummaryrefslogtreecommitdiffstats
path: root/src/ephy-navigation-action.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ephy-navigation-action.c')
-rw-r--r--src/ephy-navigation-action.c336
1 files changed, 336 insertions, 0 deletions
diff --git a/src/ephy-navigation-action.c b/src/ephy-navigation-action.c
new file mode 100644
index 000000000..3aeaef386
--- /dev/null
+++ b/src/ephy-navigation-action.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "ephy-navigation-action.h"
+#include "ephy-arrow-toolbutton.h"
+#include "ephy-window.h"
+#include "ephy-debug.h"
+
+static void ephy_navigation_action_init (EphyNavigationAction *action);
+static void ephy_navigation_action_class_init (EphyNavigationActionClass *class);
+
+static GObjectClass *parent_class = NULL;
+
+struct EphyNavigationActionPrivate
+{
+ EphyWindow *window;
+ EphyNavigationDirection direction;
+};
+
+enum
+{
+ PROP_0,
+ PROP_DIRECTION,
+ PROP_WINDOW
+};
+
+GType
+ephy_navigation_action_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo type_info =
+ {
+ sizeof (EphyNavigationActionClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ephy_navigation_action_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (EphyNavigationAction),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ephy_navigation_action_init,
+ };
+
+ type = g_type_register_static (EGG_TYPE_ACTION,
+ "EphyNavigationAction",
+ &type_info, 0);
+ }
+ return type;
+}
+
+static GtkWidget *
+new_history_menu_item (gchar *origtext,
+ const GdkPixbuf *ico)
+{
+ GtkWidget *item = gtk_image_menu_item_new ();
+ GtkWidget *hb = gtk_hbox_new (FALSE, 0);
+ GtkWidget *label = gtk_label_new (origtext);
+
+ gtk_box_pack_start (GTK_BOX (hb), label, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (item), hb);
+
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
+ gtk_image_new_from_pixbuf ((GdkPixbuf *) ico));
+
+ gtk_widget_show_all (item);
+
+ return item;
+}
+
+static void
+activate_back_or_forward_menu_item_cb (GtkWidget *menu, EphyWindow *window)
+{
+ EphyEmbed *embed;
+ int go_nth;
+
+ embed = ephy_window_get_active_embed (window);
+ g_return_if_fail (embed != NULL);
+
+ go_nth = (int)g_object_get_data (G_OBJECT(menu), "go_nth");
+
+ ephy_embed_shistory_go_nth (embed, go_nth);
+}
+
+static void
+activate_up_menu_item_cb (GtkWidget *menu, EphyWindow *window)
+{
+ EphyEmbed *embed;
+ int go_nth;
+ GSList *l;
+ gchar *url;
+
+ embed = ephy_window_get_active_embed (window);
+ g_return_if_fail (embed != NULL);
+
+ go_nth = (int)g_object_get_data (G_OBJECT(menu), "go_nth");
+
+ ephy_embed_get_go_up_list (embed, &l);
+
+ url = g_slist_nth_data (l, go_nth);
+ if (url)
+ {
+ ephy_embed_load_url (embed, url);
+ }
+
+ g_slist_foreach (l, (GFunc) g_free, NULL);
+ g_slist_free (l);
+}
+
+static void
+setup_back_or_forward_menu (EphyWindow *window, GtkMenuShell *ms, EphyNavigationDirection dir)
+{
+ int pos, count;
+ EphyEmbed *embed;
+ int start, end;
+
+ embed = ephy_window_get_active_embed (window);
+ g_return_if_fail (embed != NULL);
+
+ ephy_embed_shistory_get_pos (embed, &pos);
+ ephy_embed_shistory_count (embed, &count);
+
+ if (count == 0) return;
+
+ if (dir == EPHY_NAVIGATION_DIRECTION_BACK)
+ {
+ start = pos - 1;
+ end = -1;
+ }
+ else
+ {
+ start = pos + 1;
+ end = count;
+ }
+
+ while (start != end)
+ {
+ char *title, *url;
+ GtkWidget *item;
+ ephy_embed_shistory_get_nth (embed, start, FALSE, &url, &title);
+ item = new_history_menu_item (title ? title : url, NULL);
+ gtk_menu_shell_append (ms, item);
+ g_object_set_data (G_OBJECT (item), "go_nth", GINT_TO_POINTER (start));
+ g_signal_connect (item, "activate",
+ G_CALLBACK (activate_back_or_forward_menu_item_cb), window);
+ gtk_widget_show_all (item);
+
+ g_free (url);
+ g_free (title);
+
+ if (start < end)
+ {
+ start++;
+ }
+ else
+ {
+ start--;
+ }
+ }
+}
+
+static void
+setup_up_menu (EphyWindow *window, GtkMenuShell *ms)
+{
+ EphyEmbed *embed;
+ GSList *l;
+ GSList *li;
+ int count = 0;
+
+ embed = ephy_window_get_active_embed (window);
+ g_return_if_fail (embed != NULL);
+
+ ephy_embed_get_go_up_list (embed, &l);
+
+ for (li = l; li; li = li->next)
+ {
+ char *url = li->data;
+ GtkWidget *item;
+
+ item = new_history_menu_item (url, NULL);
+ gtk_menu_shell_append (ms, item);
+ g_object_set_data (G_OBJECT(item), "go_nth", GINT_TO_POINTER (count));
+ g_signal_connect (item, "activate",
+ G_CALLBACK (activate_up_menu_item_cb), window);
+ gtk_widget_show_all (item);
+ count ++;
+ }
+
+ g_slist_foreach (l, (GFunc) g_free, NULL);
+ g_slist_free (l);
+}
+
+static void
+menu_activated_cb (EphyArrowToolButton *w, EphyNavigationAction *b)
+{
+ EphyNavigationActionPrivate *p = b->priv;
+ GtkMenuShell *ms = ephy_arrow_toolbutton_get_menu (w);
+ EphyWindow *win = b->priv->window;
+ GList *children;
+ GList *li;
+
+ LOG ("Show navigation menu")
+
+ children = gtk_container_get_children (GTK_CONTAINER (ms));
+ for (li = children; li; li = li->next)
+ {
+ gtk_container_remove (GTK_CONTAINER (ms), li->data);
+ }
+ g_list_free (children);
+
+ switch (p->direction)
+ {
+ case EPHY_NAVIGATION_DIRECTION_UP:
+ setup_up_menu (win, ms);
+ break;
+ case EPHY_NAVIGATION_DIRECTION_FORWARD:
+ case EPHY_NAVIGATION_DIRECTION_BACK:
+ setup_back_or_forward_menu (win, ms, p->direction);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+static void
+connect_proxy (EggAction *action, GtkWidget *proxy)
+{
+ LOG ("Connect navigation action proxy")
+
+ g_signal_connect (proxy, "menu-activated",
+ G_CALLBACK (menu_activated_cb), action);
+
+ (* EGG_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
+}
+
+static void
+ephy_navigation_action_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EphyNavigationAction *nav;
+
+ nav = EPHY_NAVIGATION_ACTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_DIRECTION:
+ nav->priv->direction = g_value_get_int (value);
+ break;
+ case PROP_WINDOW:
+ nav->priv->window = EPHY_WINDOW (g_value_get_object (value));
+ break;
+ }
+}
+
+static void
+ephy_navigation_action_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EphyNavigationAction *nav;
+
+ nav = EPHY_NAVIGATION_ACTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_DIRECTION:
+ g_value_set_int (value, nav->priv->direction);
+ break;
+ case PROP_WINDOW:
+ g_value_set_object (value, nav->priv->window);
+ break;
+ }
+}
+
+static void
+ephy_navigation_action_class_init (EphyNavigationActionClass *class)
+{
+ EggActionClass *action_class;
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->set_property = ephy_navigation_action_set_property;
+ object_class->get_property = ephy_navigation_action_get_property;
+
+ parent_class = g_type_class_peek_parent (class);
+ action_class = EGG_ACTION_CLASS (class);
+
+ action_class->toolbar_item_type = EPHY_ARROW_TOOLBUTTON_TYPE;
+ action_class->connect_proxy = connect_proxy;
+
+ g_object_class_install_property (object_class,
+ PROP_DIRECTION,
+ g_param_spec_int ("direction",
+ "Direction",
+ "Direction",
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_WINDOW,
+ g_param_spec_object ("window",
+ "Window",
+ "The navigation window",
+ G_TYPE_OBJECT,
+ G_PARAM_READWRITE));
+
+}
+
+static void
+ephy_navigation_action_init (EphyNavigationAction *action)
+{
+ action->priv = g_new0 (EphyNavigationActionPrivate, 1);
+}
+
+