From ede59b054c4af72cc41108db8aedafbcae1996de Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Wed, 7 Apr 2010 17:19:25 +0200 Subject: Split EphyNavigationAction in one abstract class and two subclasses To ease understanding and further modification of the two different usages for the EphyNavigationAction class (Back/Forward and Up buttons), all the code there was split so the common one is kept in the superclass, delegating the more specific parts in the implementations of the subclasses: History (back/forward) and Up buttons. Also updated usage of this class in EphyToolbar. Bug #539716 Signed-off-by: Xan Lopez --- src/ephy-navigation-action.c | 429 +++++++------------------------------------ 1 file changed, 64 insertions(+), 365 deletions(-) (limited to 'src/ephy-navigation-action.c') diff --git a/src/ephy-navigation-action.c b/src/ephy-navigation-action.c index 35644ab0c..943126fbf 100644 --- a/src/ephy-navigation-action.c +++ b/src/ephy-navigation-action.c @@ -25,11 +25,8 @@ #include "ephy-navigation-action.h" #include "ephy-debug.h" -#include "ephy-embed-container.h" #include "ephy-embed-shell.h" -#include "ephy-embed-utils.h" #include "ephy-favicon-cache.h" -#include "ephy-gui.h" #include "ephy-history.h" #include "ephy-link.h" #include "ephy-shell.h" @@ -39,21 +36,11 @@ #include #include -#define HISTORY_ITEM_DATA_KEY "HistoryItem" -#define URL_DATA_KEY "GoURL" - #define EPHY_NAVIGATION_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_NAVIGATION_ACTION, EphyNavigationActionPrivate)) -typedef enum -{ - WEBKIT_HISTORY_BACKWARD, - WEBKIT_HISTORY_FORWARD -} WebKitHistoryType; - struct _EphyNavigationActionPrivate { EphyWindow *window; - EphyNavigationDirection direction; char *arrow_tooltip; guint statusbar_cid; }; @@ -62,7 +49,6 @@ enum { PROP_0, PROP_ARROW_TOOLTIP, - PROP_DIRECTION, PROP_WINDOW }; @@ -71,264 +57,15 @@ static void ephy_navigation_action_class_init (EphyNavigationActionClass *class) G_DEFINE_TYPE (EphyNavigationAction, ephy_navigation_action, EPHY_TYPE_LINK_ACTION) -#define MAX_LABEL_LENGTH 48 - -static GtkWidget * -new_history_menu_item (const char *origtext, - const char *address) -{ - EphyFaviconCache *cache; - EphyHistory *history; - GtkWidget *item, *image; - GdkPixbuf *icon = NULL; - GtkLabel *label; - const char *icon_address; - - g_return_val_if_fail (address != NULL && origtext != NULL, NULL); - - item = gtk_image_menu_item_new_with_label (origtext); - - label = GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))); - gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END); - gtk_label_set_max_width_chars (label, MAX_LABEL_LENGTH); - - history = EPHY_HISTORY - (ephy_embed_shell_get_global_history (embed_shell)); - icon_address = ephy_history_get_icon (history, address); - - cache = EPHY_FAVICON_CACHE - (ephy_embed_shell_get_favicon_cache (embed_shell)); - icon = ephy_favicon_cache_get (cache, icon_address); - - if (icon != NULL) - { - image = gtk_image_new_from_pixbuf (icon); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_widget_show (image); - g_object_unref (icon); - } - - gtk_widget_show (item); - - return item; -} - -static void -activate_back_or_forward_menu_item_cb (GtkWidget *menuitem, - EphyNavigationAction *action) -{ - WebKitWebHistoryItem *item; - EphyEmbed *embed; - - embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (action->priv->window)); - g_return_if_fail (embed != NULL); - - if (ephy_gui_is_middle_click ()) - { - embed = ephy_link_open (EPHY_LINK (action), "about:blank", NULL, - EPHY_LINK_NEW_TAB); - g_return_if_fail (embed != NULL); - } - - item = (WebKitWebHistoryItem*)g_object_get_data (G_OBJECT (menuitem), HISTORY_ITEM_DATA_KEY); - g_return_if_fail (item != NULL); - - webkit_web_view_go_to_back_forward_item (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed), item); -} - -static void -select_menu_item_cb (GtkWidget *menuitem, - EphyNavigationAction *action) -{ - const char *url; - GtkWidget *statusbar; - WebKitWebHistoryItem *item; - - item = (WebKitWebHistoryItem*)g_object_get_data (G_OBJECT (menuitem), HISTORY_ITEM_DATA_KEY); - if (item) - { - url = webkit_web_history_item_get_uri (item); - } - else - { - url = g_object_get_data (G_OBJECT (menuitem), URL_DATA_KEY); - g_return_if_fail (url != NULL); - } - - statusbar = ephy_window_get_statusbar (action->priv->window); - - gtk_statusbar_push (GTK_STATUSBAR (statusbar), action->priv->statusbar_cid, url); -} - -static void -deselect_menu_item_cb (GtkWidget *menuitem, - EphyNavigationAction *action) -{ - GtkWidget *statusbar; - - statusbar = ephy_window_get_statusbar (action->priv->window); - - gtk_statusbar_pop (GTK_STATUSBAR (statusbar), action->priv->statusbar_cid); -} - -static void -activate_up_menu_item_cb (GtkWidget *menuitem, - EphyNavigationAction *action) -{ - EphyEmbed *embed; - char *url; - - embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (action->priv->window)); - g_return_if_fail (embed != NULL); - - url = g_object_get_data (G_OBJECT (menuitem), URL_DATA_KEY); - g_return_if_fail (url != NULL); - - ephy_link_open (EPHY_LINK (action), url, NULL, - ephy_gui_is_middle_click () ? EPHY_LINK_NEW_TAB : 0); -} - -static GList* -webkit_construct_history_list (WebKitWebView *web_view, WebKitHistoryType hist_type) -{ - WebKitWebBackForwardList *web_back_forward_list; - GList *webkit_items; - - web_back_forward_list = webkit_web_view_get_back_forward_list (web_view); - - if (hist_type == WEBKIT_HISTORY_FORWARD) - webkit_items = g_list_reverse (webkit_web_back_forward_list_get_forward_list_with_limit (web_back_forward_list, - EPHY_WEBKIT_BACK_FORWARD_LIMIT)); - else - webkit_items = webkit_web_back_forward_list_get_back_list_with_limit (web_back_forward_list, - EPHY_WEBKIT_BACK_FORWARD_LIMIT); - - return webkit_items; -} - -static GtkWidget * -build_back_or_forward_menu (EphyNavigationAction *action) -{ - EphyWindow *window = action->priv->window; - GtkMenuShell *menu; - EphyEmbed *embed; - GList *list, *l; - WebKitWebView *web_view; - - embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); - g_return_val_if_fail (embed != NULL, NULL); - - web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed); - g_return_val_if_fail (web_view != NULL, NULL); - - if (action->priv->direction == EPHY_NAVIGATION_DIRECTION_BACK) - list = webkit_construct_history_list (web_view, - WEBKIT_HISTORY_BACKWARD); - else - list = webkit_construct_history_list (web_view, - WEBKIT_HISTORY_FORWARD); - - menu = GTK_MENU_SHELL (gtk_menu_new ()); - - l = list; - for (l = list; l != NULL; l = l->next) - { - GtkWidget *item; - WebKitWebHistoryItem *hitem; - const char *url; - char *title; - - hitem = (WebKitWebHistoryItem*)l->data; - url = webkit_web_history_item_get_uri (hitem); - - title = g_strdup (webkit_web_history_item_get_title (hitem)); - - if ((title == NULL || g_strstrip (title)[0] == '\0')) - item = new_history_menu_item (url, url); - else - item = new_history_menu_item (title, url); - - g_free (title); - - g_object_set_data_full (G_OBJECT (item), HISTORY_ITEM_DATA_KEY, - g_object_ref (hitem), g_object_unref); - - g_signal_connect (item, "activate", - G_CALLBACK (activate_back_or_forward_menu_item_cb), - action); - g_signal_connect (item, "select", - G_CALLBACK (select_menu_item_cb), - action); - g_signal_connect (item, "deselect", - G_CALLBACK (deselect_menu_item_cb), - action); - - gtk_menu_shell_append (menu, item); - gtk_widget_show_all (item); - } - - g_list_free (list); - - return GTK_WIDGET (menu); -} +#define MAX_LABEL_LENGTH 48 static GtkWidget * -build_up_menu (EphyNavigationAction *action) +build_dropdown_menu (EphyNavigationAction *action) { - EphyWindow *window = action->priv->window; - EphyEmbed *embed; - EphyHistory *history; - GtkMenuShell *menu; - GtkWidget *item; - GSList *list, *l; - char *url; + EphyNavigationActionClass *class = EPHY_NAVIGATION_ACTION_GET_CLASS (action); - embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); - g_return_val_if_fail (embed != NULL, NULL); - - menu = GTK_MENU_SHELL (gtk_menu_new ()); - - history = EPHY_HISTORY - (ephy_embed_shell_get_global_history (embed_shell)); - - list = ephy_web_view_get_go_up_list (ephy_embed_get_web_view (embed)); - - for (l = list; l != NULL; l = l->next) - { - EphyNode *node; - const char *title = NULL; - - url = g_strdup (l->data); - - if (url == NULL) continue; - - node = ephy_history_get_page (history, url); - if (node != NULL) - { - title = ephy_node_get_property_string (node, EPHY_NODE_PAGE_PROP_TITLE); - } - - item = new_history_menu_item (title ? title : url, url); - - g_object_set_data_full (G_OBJECT (item), URL_DATA_KEY, url, - (GDestroyNotify) g_free); - g_signal_connect (item, "activate", - G_CALLBACK (activate_up_menu_item_cb), action); - g_signal_connect (item, "select", - G_CALLBACK (select_menu_item_cb), action); - g_signal_connect (item, "deselect", - G_CALLBACK (deselect_menu_item_cb), action); - - gtk_menu_shell_append (menu, item); - gtk_widget_show (item); - } - - /* the list data has been consumed */ - g_slist_foreach (list, (GFunc) g_free, NULL); - g_slist_free (list); - - return GTK_WIDGET (menu); + return class->build_dropdown_menu (action); } static void @@ -337,22 +74,9 @@ menu_activated_cb (GtkMenuToolButton *button, { GtkWidget *menu = NULL; - LOG ("menu_activated_cb dir %d", action->priv->direction); - - switch (action->priv->direction) - { - case EPHY_NAVIGATION_DIRECTION_UP: - menu = build_up_menu (action); - break; - case EPHY_NAVIGATION_DIRECTION_FORWARD: - case EPHY_NAVIGATION_DIRECTION_BACK: - menu = build_back_or_forward_menu (action); - break; - default: - g_assert_not_reached (); - break; - } + LOG ("menu_activated_cb"); + menu = build_dropdown_menu (action); gtk_menu_tool_button_set_menu (button, menu); } @@ -381,75 +105,6 @@ connect_proxy (GtkAction *gaction, GTK_ACTION_CLASS (ephy_navigation_action_parent_class)->connect_proxy (gaction, proxy); } -static void -ephy_navigation_action_activate (GtkAction *gtk_action) -{ - EphyNavigationAction *action = EPHY_NAVIGATION_ACTION (gtk_action); - EphyWindow *window = action->priv->window; - EphyEmbed *embed; - WebKitWebView *web_view; - - embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); - g_return_if_fail (embed != NULL); - - web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed); - - if (action->priv->direction == EPHY_NAVIGATION_DIRECTION_BACK) - { - if (ephy_gui_is_middle_click ()) - { - embed = ephy_shell_new_tab (ephy_shell_get_default (), - EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (embed))), - embed, - NULL, - EPHY_NEW_TAB_IN_EXISTING_WINDOW); - web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed); - } - webkit_web_view_go_back (web_view); - } - else if (action->priv->direction == EPHY_NAVIGATION_DIRECTION_FORWARD) - { - if (ephy_gui_is_middle_click ()) - { - const char *forward_uri; - WebKitWebHistoryItem *forward_item; - WebKitWebBackForwardList *history; - - /* Forward history is not copied when opening - a new tab, so get the forward URI manually - and load it */ - history = webkit_web_view_get_back_forward_list (EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed)); - forward_item = webkit_web_back_forward_list_get_forward_item (history); - forward_uri = webkit_web_history_item_get_original_uri (forward_item); - - embed = ephy_shell_new_tab (ephy_shell_get_default (), - EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (embed))), - embed, - NULL, - EPHY_NEW_TAB_IN_EXISTING_WINDOW); - - web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed); - webkit_web_view_load_uri (web_view, forward_uri); - } - else - { - webkit_web_view_go_forward (web_view); - } - } - else if (action->priv->direction == EPHY_NAVIGATION_DIRECTION_UP) - { - GSList *up_list; - - up_list = ephy_web_view_get_go_up_list (ephy_embed_get_web_view (embed)); - ephy_link_open (EPHY_LINK (action), - up_list->data, - NULL, - ephy_gui_is_middle_click () ? EPHY_LINK_NEW_TAB : 0); - g_slist_foreach (up_list, (GFunc) g_free, NULL); - g_slist_free (up_list); - } -} - static void ephy_navigation_action_init (EphyNavigationAction *action) { @@ -480,9 +135,6 @@ ephy_navigation_action_set_property (GObject *object, nav->priv->arrow_tooltip = g_value_dup_string (value); g_object_notify (object, "tooltip"); break; - case PROP_DIRECTION: - nav->priv->direction = g_value_get_int (value); - break; case PROP_WINDOW: { GtkWidget *statusbar; @@ -513,9 +165,6 @@ ephy_navigation_action_get_property (GObject *object, case PROP_ARROW_TOOLTIP: g_value_set_string (value, nav->priv->arrow_tooltip); break; - case PROP_DIRECTION: - g_value_set_int (value, nav->priv->direction); - break; case PROP_WINDOW: g_value_set_object (value, nav->priv->window); break; @@ -534,7 +183,8 @@ ephy_navigation_action_class_init (EphyNavigationActionClass *class) action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON; action_class->connect_proxy = connect_proxy; - action_class->activate = ephy_navigation_action_activate; + + class->build_dropdown_menu = NULL; g_object_class_install_property (object_class, PROP_ARROW_TOOLTIP, @@ -542,13 +192,6 @@ ephy_navigation_action_class_init (EphyNavigationActionClass *class) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (object_class, - PROP_DIRECTION, - g_param_spec_int ("direction", NULL, NULL, - 0, - G_MAXINT, - 0, - G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); g_object_class_install_property (object_class, PROP_WINDOW, g_param_spec_object ("window", NULL, NULL, @@ -557,3 +200,59 @@ ephy_navigation_action_class_init (EphyNavigationActionClass *class) g_type_class_add_private (object_class, sizeof (EphyNavigationActionPrivate)); } + +EphyWindow * +_ephy_navigation_action_get_window (EphyNavigationAction *action) +{ + g_return_val_if_fail (EPHY_IS_NAVIGATION_ACTION (action), NULL); + + return action->priv->window; +} + +guint +_ephy_navigation_action_get_statusbar_context_id (EphyNavigationAction *action) +{ + g_return_val_if_fail (EPHY_IS_NAVIGATION_ACTION (action), 0); + + return action->priv->statusbar_cid; +} + +GtkWidget * +_ephy_navigation_action_new_history_menu_item (const char *origtext, + const char *address) +{ + EphyFaviconCache *cache; + EphyHistory *history; + GtkWidget *item, *image; + GdkPixbuf *icon = NULL; + GtkLabel *label; + const char *icon_address; + + g_return_val_if_fail (address != NULL && origtext != NULL, NULL); + + item = gtk_image_menu_item_new_with_label (origtext); + + label = GTK_LABEL (gtk_bin_get_child (GTK_BIN (item))); + gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END); + gtk_label_set_max_width_chars (label, MAX_LABEL_LENGTH); + + history = EPHY_HISTORY + (ephy_embed_shell_get_global_history (embed_shell)); + icon_address = ephy_history_get_icon (history, address); + + cache = EPHY_FAVICON_CACHE + (ephy_embed_shell_get_favicon_cache (embed_shell)); + icon = ephy_favicon_cache_get (cache, icon_address); + + if (icon != NULL) + { + image = gtk_image_new_from_pixbuf (icon); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_widget_show (image); + g_object_unref (icon); + } + + gtk_widget_show (item); + + return item; +} -- cgit v1.2.3