[evince] Use GAction instead of GtkAction for EvHistoryAction



commit 61f5ae15df1164ed0aee976258e2d705e5250bbb
Author: Carlos Garcia Campos <carlosgc gnome org>
Date:   Fri Jun 20 11:19:38 2014 +0200

    Use GAction instead of GtkAction for EvHistoryAction
    
    Merge EvHistoryAction and EvHistoryActionWidget into a single widget
    derived from GtkBox that uses GAction.

 po/POTFILES.in                   |    2 +-
 shell/Makefile.am                |    2 -
 shell/ev-history-action-widget.c |  323 --------------------------------------
 shell/ev-history-action-widget.h |   58 -------
 shell/ev-history-action.c        |  263 +++++++++++++++++++++++++------
 shell/ev-history-action.h        |   11 +-
 shell/ev-toolbar.c               |   12 +-
 shell/ev-window.c                |   33 ++---
 shell/ev-window.h                |    2 +
 9 files changed, 244 insertions(+), 462 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index de79679..86c7443 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -35,7 +35,7 @@ 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-history-action.c
 shell/ev-keyring.c
 shell/ev-loading-message.c
 shell/ev-password-view.c
diff --git a/shell/Makefile.am b/shell/Makefile.am
index ac24137..5024554 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -25,8 +25,6 @@ evince_SOURCES=                               \
        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            \
diff --git a/shell/ev-history-action.c b/shell/ev-history-action.c
index 738c1d2..2d29cec 100644
--- a/shell/ev-history-action.c
+++ b/shell/ev-history-action.c
@@ -19,94 +19,260 @@
  */
 
 #include "config.h"
-
 #include "ev-history-action.h"
-#include "ev-history-action-widget.h"
+
+#include <glib/gi18n.h>
 
 enum {
-        ACTIVATED,
-        LAST_SIGNAL
+        PROP_0,
+
+        PROP_HISTORY
 };
 
+typedef enum {
+        EV_HISTORY_ACTION_BUTTON_BACK,
+        EV_HISTORY_ACTION_BUTTON_FORWARD
+} EvHistoryActionButton;
 
 struct _EvHistoryActionPrivate {
+        GtkWidget *back_button;
+        GtkWidget *forward_button;
+
         EvHistory *history;
         gboolean   popup_shown;
 };
 
-G_DEFINE_TYPE (EvHistoryAction, ev_history_action, GTK_TYPE_ACTION)
+G_DEFINE_TYPE (EvHistoryAction, ev_history_action, GTK_TYPE_BOX)
 
-static guint signals[LAST_SIGNAL] = { 0 };
+static void
+history_menu_link_activated (GtkMenuItem     *item,
+                             EvHistoryAction *history_action)
+{
+        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_action->priv->history, link);
+}
 
 static void
-popup_shown_cb (GObject         *history_widget,
-                GParamSpec      *pspec,
-                EvHistoryAction *history_action)
+popup_menu_hide_cb (GtkMenu         *menu,
+                    EvHistoryAction *history_action)
+{
+        history_action->priv->popup_shown = FALSE;
+}
+
+static void
+ev_history_action_show_popup (EvHistoryAction       *history_action,
+                              EvHistoryActionButton  action_button,
+                              guint                  button,
+                              guint32                event_time)
 {
-        g_object_get (history_widget, "popup-shown", &history_action->priv->popup_shown, NULL);
+        GtkWidget *menu;
+        GList     *list = NULL;
+        GList     *l;
+
+        switch (action_button) {
+        case EV_HISTORY_ACTION_BUTTON_BACK:
+                list = ev_history_get_back_list (history_action->priv->history);
+                break;
+        case EV_HISTORY_ACTION_BUTTON_FORWARD:
+                list = ev_history_get_forward_list (history_action->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_action, 0);
+                gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+                gtk_widget_show (item);
+        }
+        g_list_free (list);
+
+        history_action->priv->popup_shown = TRUE;
+        g_signal_connect (menu, "hide",
+                          G_CALLBACK (popup_menu_hide_cb),
+                          history_action);
+        gtk_menu_popup (GTK_MENU (menu),
+                        NULL, NULL, NULL, NULL,
+                        button, event_time);
+}
+
+static void
+ev_history_action_finalize (GObject *object)
+{
+        EvHistoryAction *history_action = EV_HISTORY_ACTION (object);
+
+        if (history_action->priv->history) {
+                g_object_remove_weak_pointer (G_OBJECT (history_action->priv->history),
+                                              (gpointer)&history_action->priv->history);
+        }
+
+        G_OBJECT_CLASS (ev_history_action_parent_class)->finalize (object);
 }
 
 static void
-connect_proxy (GtkAction *action,
-               GtkWidget *proxy)
+ev_history_action_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
 {
-        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);
+        EvHistoryAction *history_action = EV_HISTORY_ACTION (object);
+
+        switch (prop_id) {
+        case PROP_HISTORY:
+                history_action->priv->history = g_value_get_object (value);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
         }
+}
+
+static void
+ev_history_action_constructed (GObject *object)
+{
+        EvHistoryAction *history_action = EV_HISTORY_ACTION (object);
+
+        G_OBJECT_CLASS (ev_history_action_parent_class)->constructed (object);
 
-        GTK_ACTION_CLASS (ev_history_action_parent_class)->connect_proxy (action, proxy);
+        g_object_add_weak_pointer (G_OBJECT (history_action->priv->history),
+                                   (gpointer)&history_action->priv->history);
 }
 
 static void
 ev_history_action_class_init (EvHistoryActionClass *class)
 {
-        GObjectClass   *object_class = G_OBJECT_CLASS (class);
-        GtkActionClass *action_class = GTK_ACTION_CLASS (class);
+        GObjectClass *object_class = G_OBJECT_CLASS (class);
 
-        action_class->toolbar_item_type = EV_TYPE_HISTORY_ACTION_WIDGET;
-        action_class->connect_proxy = connect_proxy;
+        object_class->constructed = ev_history_action_constructed;
+        object_class->finalize = ev_history_action_finalize;
+        object_class->set_property = ev_history_action_set_property;
 
-        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_object_class_install_property (object_class,
+                                         PROP_HISTORY,
+                                         g_param_spec_object ("history",
+                                                              "History",
+                                                              "The History",
+                                                              EV_TYPE_HISTORY,
+                                                              G_PARAM_WRITABLE |
+                                                              G_PARAM_CONSTRUCT_ONLY |
+                                                              G_PARAM_STATIC_STRINGS));
 
         g_type_class_add_private (object_class, sizeof (EvHistoryActionPrivate));
 }
 
-static void
-ev_history_action_init (EvHistoryAction *action)
+static gboolean
+button_pressed (GtkWidget       *button,
+                GdkEventButton  *event,
+                EvHistoryAction *history_action)
 {
-        action->priv = G_TYPE_INSTANCE_GET_PRIVATE (action, EV_TYPE_HISTORY_ACTION, EvHistoryActionPrivate);
+        EvHistoryActionPrivate *priv = history_action->priv;
+
+        /* TODO: Show the popup menu after a long press too */
+        switch (event->button) {
+        case GDK_BUTTON_SECONDARY:
+                ev_history_action_show_popup (history_action,
+                                              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;
 }
 
-void
-ev_history_action_set_history (EvHistoryAction *action,
-                               EvHistory       *history)
+static GtkWidget *
+ev_history_action_create_button (EvHistoryAction       *history_action,
+                                 EvHistoryActionButton  action_button)
 {
-        GSList *proxies, *l;
+        GtkWidget   *button;
+        GtkWidget   *image;
+        const gchar *icon_name = NULL;
+        const gchar *tooltip_text = NULL;
+        const gchar *action_name = NULL;
+        gboolean     rtl;
 
-        g_return_if_fail (EV_IS_HISTORY_ACTION (action));
-        g_return_if_fail (EV_IS_HISTORY (history));
+        rtl = (gtk_widget_get_direction (GTK_WIDGET (history_action)) == GTK_TEXT_DIR_RTL);
 
-        if (action->priv->history == history)
-                return;
+        button = gtk_button_new ();
+        gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
+        g_signal_connect (button, "button-press-event",
+                          G_CALLBACK (button_pressed),
+                          history_action);
 
-        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);
+        switch (action_button) {
+        case EV_HISTORY_ACTION_BUTTON_BACK:
+                icon_name = rtl ? "go-previous-rtl-symbolic" : "go-previous-symbolic";
+                tooltip_text = _("Go to previous history item");
+                action_name = "win.go-back-history";
+                break;
+        case EV_HISTORY_ACTION_BUTTON_FORWARD:
+                icon_name = rtl ? "go-next-rtl-symbolic" : "go-next-symbolic";
+                tooltip_text = _("Go to next history item");
+                action_name = "win.go-forward-history";
+                break;
         }
+
+        image = gtk_image_new ();
+        gtk_actionable_set_action_name (GTK_ACTIONABLE (button), action_name);
+        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_init (EvHistoryAction *history_action)
+{
+        GtkWidget              *box = GTK_WIDGET (history_action);
+        GtkStyleContext        *style_context;
+        EvHistoryActionPrivate *priv;
+
+        history_action->priv = G_TYPE_INSTANCE_GET_PRIVATE (history_action, EV_TYPE_HISTORY_ACTION, 
EvHistoryActionPrivate);
+        priv = history_action->priv;
+
+        gtk_orientable_set_orientation (GTK_ORIENTABLE (box), GTK_ORIENTATION_HORIZONTAL);
+        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_create_button (history_action,
+                                                             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_create_button (history_action,
+                                                                EV_HISTORY_ACTION_BUTTON_FORWARD);
+        gtk_container_add (GTK_CONTAINER (box), priv->forward_button);
+        gtk_widget_show (priv->forward_button);
+}
+
+GtkWidget *
+ev_history_action_new (EvHistory *history)
+{
+        g_return_val_if_fail (EV_IS_HISTORY (history), NULL);
+
+        return GTK_WIDGET (g_object_new (EV_TYPE_HISTORY_ACTION, "history", history, NULL));
 }
 
 gboolean
@@ -116,4 +282,3 @@ ev_history_action_get_popup_shown (EvHistoryAction *action)
 
         return action->priv->popup_shown;
 }
-
diff --git a/shell/ev-history-action.h b/shell/ev-history-action.h
index 4badb14..bb29de6 100644
--- a/shell/ev-history-action.h
+++ b/shell/ev-history-action.h
@@ -39,20 +39,19 @@ typedef struct _EvHistoryActionClass   EvHistoryActionClass;
 typedef struct _EvHistoryActionPrivate EvHistoryActionPrivate;
 
 struct _EvHistoryAction {
-        GtkAction parent;
+        GtkBox parent;
 
         EvHistoryActionPrivate *priv;
 };
 
 struct _EvHistoryActionClass {
-        GtkActionClass parent_class;
+        GtkBoxClass parent_class;
 };
 
-GType    ev_history_action_get_type        (void);
+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);
+GtkWidget *ev_history_action_new             (EvHistory       *history);
+gboolean   ev_history_action_get_popup_shown (EvHistoryAction *action);
 
 G_END_DECLS
 
diff --git a/shell/ev-toolbar.c b/shell/ev-toolbar.c
index 72feeae..5e7278c 100644
--- a/shell/ev-toolbar.c
+++ b/shell/ev-toolbar.c
@@ -44,6 +44,7 @@ struct _EvToolbarPrivate {
 
         GtkWidget *view_menu_button;
         GtkWidget *action_menu_button;
+        GtkWidget *history_action;
         GMenu *bookmarks_section;
 };
 
@@ -243,12 +244,16 @@ ev_toolbar_constructed (GObject *object)
         gtk_widget_show (tool_item);
 
         /* History */
-        action = gtk_action_group_get_action (action_group, "History");
-        tool_item = gtk_action_create_tool_item (action);
+        hbox = ev_history_action_new (ev_window_get_history (ev_toolbar->priv->window));
+        ev_toolbar->priv->history_action = hbox;
+        tool_item = GTK_WIDGET (gtk_tool_item_new ());
         if (rtl)
                 gtk_widget_set_margin_left (tool_item, 12);
         else
                 gtk_widget_set_margin_right (tool_item, 12);
+        gtk_container_add (GTK_CONTAINER (tool_item), hbox);
+        gtk_widget_show (hbox);
+
         gtk_container_add (GTK_CONTAINER (ev_toolbar), tool_item);
         gtk_widget_show (tool_item);
 
@@ -391,8 +396,7 @@ 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)))
+        if (ev_history_action_get_popup_shown (EV_HISTORY_ACTION (ev_toolbar->priv->history_action)))
                 return TRUE;
 
         return FALSE;
diff --git a/shell/ev-window.c b/shell/ev-window.c
index aa0a68a..ac9868a 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -64,7 +64,6 @@
 #include "ev-message-area.h"
 #include "ev-metadata.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"
@@ -243,7 +242,6 @@ struct _EvWindowPrivate {
 
 #define PAGE_SELECTOR_ACTION   "PageSelector"
 #define ZOOM_CONTROL_ACTION    "ViewZoom"
-#define HISTORY_ACTION          "History"
 
 #define GS_LOCKDOWN_SCHEMA_NAME  "org.gnome.desktop.lockdown"
 #define GS_LOCKDOWN_SAVE         "disable-save-to-disk"
@@ -554,8 +552,12 @@ ev_window_update_actions_sensitivity (EvWindow *ev_window)
                ev_window_set_action_enabled (ev_window, "select-page", FALSE);
        }
 
-       ev_window_set_action_sensitive (ev_window, "History",
-                                       !ev_history_is_frozen (ev_window->priv->history));
+       ev_window_set_action_enabled (ev_window, "go-back-history",
+                                     !ev_history_is_frozen (ev_window->priv->history) &&
+                                     ev_history_can_go_back (ev_window->priv->history));
+       ev_window_set_action_enabled (ev_window, "go-forward-history",
+                                     !ev_history_is_frozen (ev_window->priv->history) &&
+                                     ev_history_can_go_forward (ev_window->priv->history));
 
        ev_window_set_action_enabled (ev_window, "caret-navigation",
                                      has_pages &&
@@ -5337,8 +5339,6 @@ ev_window_show_find_bar (EvWindow *ev_window,
 
        if (restart && ev_window->priv->find_job)
                ev_window_find_restart (ev_window);
-
-       ev_window_set_action_sensitive (ev_window, "History", FALSE);
 }
 
 static void
@@ -5359,8 +5359,6 @@ ev_window_close_find_bar (EvWindow *ev_window)
        g_action_group_change_action_state (G_ACTION_GROUP (ev_window), "toggle-find", g_variant_new_boolean 
(FALSE));
 
        ev_history_thaw (ev_window->priv->history);
-
-       ev_window_set_action_sensitive (ev_window, "History", TRUE);
 }
 
 static void
@@ -5869,8 +5867,6 @@ history_changed_cb (EvHistory *history,
                                      ev_history_can_go_back (window->priv->history));
        ev_window_set_action_enabled (window, "go-forward-history",
                                      ev_history_can_go_forward (window->priv->history));
-       ev_window_set_action_sensitive (window, "History",
-                                       !ev_history_is_frozen (window->priv->history));
 }
 
 static void
@@ -5982,15 +5978,6 @@ register_custom_actions (EvWindow *window, GtkActionGroup *group)
                          G_CALLBACK (zoom_action_activated_cb), window);
        gtk_action_group_add_action (group, action);
        g_object_unref (action);
-
-       action = g_object_new (EV_TYPE_HISTORY_ACTION,
-                              "name", HISTORY_ACTION,
-                              "label", _("History"),
-                              NULL);
-       ev_history_action_set_history (EV_HISTORY_ACTION (action),
-                                      window->priv->history);
-       gtk_action_group_add_action (group, action);
-       g_object_unref (action);
 }
 
 static void
@@ -7376,3 +7363,11 @@ ev_window_get_bookmarks_menu (EvWindow *ev_window)
 
        return G_MENU_MODEL (ev_window->priv->bookmarks_menu);
 }
+
+EvHistory *
+ev_window_get_history (EvWindow *ev_window)
+{
+       g_return_val_if_fail (EV_WINDOW (ev_window), NULL);
+
+       return ev_window->priv->history;
+}
diff --git a/shell/ev-window.h b/shell/ev-window.h
index 6c123d0..d074073 100644
--- a/shell/ev-window.h
+++ b/shell/ev-window.h
@@ -27,6 +27,7 @@
 #include <gtk/gtk.h>
 
 #include "ev-link.h"
+#include "ev-history.h"
 
 G_BEGIN_DECLS
 
@@ -90,6 +91,7 @@ GtkUIManager   *ev_window_get_ui_manager                 (EvWindow       *ev_win
 GtkActionGroup *ev_window_get_main_action_group          (EvWindow       *ev_window);
 GtkActionGroup *ev_window_get_zoom_selector_action_group (EvWindow       *ev_window);
 GMenuModel     *ev_window_get_bookmarks_menu             (EvWindow       *ev_window);
+EvHistory      *ev_window_get_history                    (EvWindow       *ev_window);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]