[evince] Add new zoom combo widget for the toolbar



commit 3ce4d8884174965e03cdb9f16c3c30e95ec69d63
Author: Carlos Garcia Campos <carlosgc gnome org>
Date:   Sun Nov 4 20:52:30 2012 +0100

    Add new zoom combo widget for the toolbar
    
    It's a combo box with an entry to always show the current real zoom
    level and allow the user to enter a zoom level manually as well.

 po/POTFILES.in                |    1 +
 shell/Makefile.am             |    4 +
 shell/ev-zoom-action-widget.c |  410 +++++++++++++++++++++++++++++++++++++++++
 shell/ev-zoom-action-widget.h |   61 ++++++
 shell/ev-zoom-action.c        |  152 +++++++++++++++
 shell/ev-zoom-action.h        |   61 ++++++
 6 files changed, 689 insertions(+), 0 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9056b2f..a3ec5cd 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -55,5 +55,6 @@ shell/ev-sidebar-thumbnails.c
 shell/ev-utils.c
 shell/ev-window.c
 shell/ev-window-title.c
+shell/ev-zoom-action-widget.c
 shell/main.c
 [type: gettext/glade]shell/evince-appmenu.ui
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 60bf935..ffcb8bf 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -73,6 +73,10 @@ evince_SOURCES=				\
 	ev-window.h			\
 	ev-window-title.c		\
 	ev-window-title.h		\
+	ev-zoom-action.c		\
+	ev-zoom-action.h		\
+	ev-zoom-action-widget.c		\
+	ev-zoom-action-widget.h		\
 	ev-sidebar.c			\
 	ev-sidebar.h			\
 	ev-sidebar-annotations.c	\
diff --git a/shell/ev-zoom-action-widget.c b/shell/ev-zoom-action-widget.c
new file mode 100644
index 0000000..0579a78
--- /dev/null
+++ b/shell/ev-zoom-action-widget.c
@@ -0,0 +1,410 @@
+/* ev-zoom-action-widget.c
+ *  this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2012 Carlos Garcia Campos  <carlosgc gnome org>
+ *
+ * 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-zoom-action-widget.h"
+
+#include <glib/gi18n.h>
+
+struct _EvZoomActionWidgetPrivate {
+        GtkWidget       *combo;
+
+        EvDocumentModel *model;
+        gulong           combo_changed_handler;
+};
+
+#define EV_ZOOM_BEST_FIT  (-3.0)
+#define EV_ZOOM_FIT_WIDTH (-4.0)
+#define EV_ZOOM_SEPARATOR (-5.0)
+
+static const struct {
+        const gchar *name;
+        float        level;
+} zoom_levels[] = {
+        { N_("Best Fit"),       EV_ZOOM_BEST_FIT  },
+        { N_("Fit Page Width"), EV_ZOOM_FIT_WIDTH },
+        { NULL,                 EV_ZOOM_SEPARATOR },
+        { N_("50%"), 0.5 },
+        { N_("70%"), 0.7071067811 },
+        { N_("85%"), 0.8408964152 },
+        { N_("100%"), 1.0 },
+        { N_("125%"), 1.1892071149 },
+        { N_("150%"), 1.4142135623 },
+        { N_("175%"), 1.6817928304 },
+        { N_("200%"), 2.0 },
+        { N_("300%"), 2.8284271247 },
+        { N_("400%"), 4.0 },
+        { N_("800%"), 8.0 },
+        { N_("1600%"), 16.0 },
+        { N_("3200%"), 32.0 },
+        { N_("6400%"), 64.0 }
+};
+
+enum {
+        TEXT_COLUMN,
+        IS_SEPARATOR_COLUMN,
+
+        N_COLUMNS
+};
+
+G_DEFINE_TYPE (EvZoomActionWidget, ev_zoom_action_widget, GTK_TYPE_TOOL_ITEM)
+
+#define EPSILON 0.000001
+
+static void
+ev_zoom_action_widget_set_zoom_level (EvZoomActionWidget *control,
+                                      float               zoom)
+{
+        GtkWidget *entry = gtk_bin_get_child (GTK_BIN (control->priv->combo));
+        gchar     *zoom_str;
+        float      zoom_perc;
+        guint      i;
+
+        for (i = 3; i < G_N_ELEMENTS (zoom_levels); i++) {
+                if (ABS (zoom - zoom_levels[i].level) < EPSILON) {
+                        gtk_entry_set_text (GTK_ENTRY (entry), zoom_levels[i].name);
+                        return;
+                }
+        }
+
+        zoom_perc = zoom * 100.;
+        if (ABS ((gint)zoom_perc - zoom_perc) < 0.001)
+                zoom_str = g_strdup_printf ("%d%%", (gint)zoom_perc);
+        else
+                zoom_str = g_strdup_printf ("%.2f%%", zoom_perc);
+        gtk_entry_set_text (GTK_ENTRY (entry), zoom_str);
+        g_free (zoom_str);
+}
+
+static void
+ev_zoom_action_widget_update_zoom_level (EvZoomActionWidget *control)
+{
+        float      zoom = ev_document_model_get_scale (control->priv->model);
+        GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (control));
+
+        zoom *= 72.0 / ev_document_misc_get_screen_dpi (screen);
+        ev_zoom_action_widget_set_zoom_level (control, zoom);
+}
+
+static void
+zoom_changed_cb (EvDocumentModel    *model,
+                 GParamSpec         *pspec,
+                 EvZoomActionWidget *control)
+{
+        ev_zoom_action_widget_update_zoom_level (control);
+}
+
+static void
+ev_zoom_action_widget_update_sizing_mode (EvZoomActionWidget *control)
+{
+        GtkWidget   *entry = gtk_bin_get_child (GTK_BIN (control->priv->combo));
+        EvSizingMode mode = ev_document_model_get_sizing_mode (control->priv->model);
+        const gchar *icon_name = NULL;
+        const gchar *tooltip = NULL;
+
+        switch (mode) {
+        case EV_SIZING_BEST_FIT:
+                icon_name = EV_STOCK_ZOOM_PAGE;
+                tooltip = _("Best Fit");
+                break;
+        case EV_SIZING_FIT_WIDTH:
+                icon_name = EV_STOCK_ZOOM_WIDTH;
+                tooltip = _("Fit Page Width");
+                break;
+        case EV_SIZING_FREE:
+                break;
+        }
+
+        gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, icon_name);
+        gtk_entry_set_icon_tooltip_text (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, tooltip);
+}
+
+static void
+sizing_mode_changed_cb (EvDocumentModel    *model,
+                        GParamSpec         *pspec,
+                        EvZoomActionWidget *control)
+{
+        ev_zoom_action_widget_update_sizing_mode (control);
+}
+
+static void
+document_changed_cb (EvDocumentModel    *model,
+                     GParamSpec         *pspec,
+                     EvZoomActionWidget *control)
+{
+        if (!ev_document_model_get_document (model))
+                return;
+
+        ev_zoom_action_widget_update_zoom_level (control);
+        ev_zoom_action_widget_update_sizing_mode (control);
+}
+
+static void
+combo_changed_cb (GtkComboBox        *combo,
+                  EvZoomActionWidget *control)
+{
+        gint         index;
+        float        zoom;
+        EvSizingMode mode;
+
+        index = gtk_combo_box_get_active (combo);
+        if (index == -1)
+                return;
+
+        zoom = zoom_levels[index].level;
+        if (zoom == EV_ZOOM_BEST_FIT)
+                mode = EV_SIZING_BEST_FIT;
+        else if (zoom == EV_ZOOM_FIT_WIDTH)
+                mode = EV_SIZING_FIT_WIDTH;
+        else
+                mode = EV_SIZING_FREE;
+
+        ev_document_model_set_sizing_mode (control->priv->model, mode);
+        if (mode == EV_SIZING_FREE) {
+                GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (control));
+
+                ev_document_model_set_scale (control->priv->model,
+                                             zoom * ev_document_misc_get_screen_dpi (screen) / 72.0);
+        }
+}
+
+static void
+combo_activated_cb (GtkEntry           *entry,
+                    EvZoomActionWidget *control)
+{
+        GdkScreen   *screen;
+        double       zoom_perc;
+        float        zoom;
+        const gchar *text = gtk_entry_get_text (entry);
+        gchar       *end_ptr = NULL;
+
+        if (!text || text[0] == '\0') {
+                ev_zoom_action_widget_update_zoom_level (control);
+                return;
+        }
+
+        zoom_perc = g_strtod (text, &end_ptr);
+        if (end_ptr && end_ptr[0] != '\0' && end_ptr[0] != '%') {
+                ev_zoom_action_widget_update_zoom_level (control);
+                return;
+        }
+
+        screen = gtk_widget_get_screen (GTK_WIDGET (control));
+        zoom = zoom_perc / 100.;
+        ev_document_model_set_sizing_mode (control->priv->model, EV_SIZING_FREE);
+        ev_document_model_set_scale (control->priv->model,
+                                     zoom * ev_document_misc_get_screen_dpi (screen) / 72.0);
+}
+
+static gchar *
+combo_format_entry_text (GtkComboBox        *combo,
+                         const gchar        *path,
+                         EvZoomActionWidget *control)
+{
+        GtkTreeModel *model;
+        GtkTreeIter   iter;
+        gchar        *text;
+
+        model = gtk_combo_box_get_model (combo);
+        gtk_tree_model_get_iter_from_string (model, &iter, path);
+        gtk_tree_model_get (model, &iter, TEXT_COLUMN, &text, -1);
+
+        return text;
+}
+
+static gboolean
+row_is_separator (GtkTreeModel *model,
+                  GtkTreeIter  *iter,
+                  gpointer      data)
+{
+        gboolean is_sep;
+
+        gtk_tree_model_get (model, iter, IS_SEPARATOR_COLUMN, &is_sep, -1);
+
+        return is_sep;
+}
+
+static void
+ev_zoom_action_widget_finalize (GObject *object)
+{
+        EvZoomActionWidget *control = EV_ZOOM_ACTION_WIDGET (object);
+
+        ev_zoom_action_widget_set_model (control, NULL);
+
+        G_OBJECT_CLASS (ev_zoom_action_widget_parent_class)->finalize (object);
+}
+
+static void
+fill_combo_model (GtkListStore *model,
+                  guint         max_level)
+{
+        guint i;
+
+        for (i = 0; i < max_level; i++) {
+                GtkTreeIter iter;
+
+                gtk_list_store_append (model, &iter);
+                gtk_list_store_set (model, &iter,
+                                    TEXT_COLUMN, _(zoom_levels[i].name),
+                                    IS_SEPARATOR_COLUMN, zoom_levels[i].name == NULL,
+                                    -1);
+        }
+}
+
+static void
+ev_zoom_action_widget_init (EvZoomActionWidget *control)
+{
+        EvZoomActionWidgetPrivate *priv;
+        GtkWidget                 *entry;
+        GtkWidget                 *vbox;
+        GtkCellRenderer           *renderer;
+        GtkListStore              *store;
+
+        control->priv = G_TYPE_INSTANCE_GET_PRIVATE (control, EV_TYPE_ZOOM_ACTION_WIDGET, EvZoomActionWidgetPrivate);
+        priv = control->priv;
+
+        store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_BOOLEAN);
+        fill_combo_model (store, G_N_ELEMENTS (zoom_levels));
+
+        priv->combo = gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL (store));
+        gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (priv->combo), FALSE);
+        g_object_unref (store);
+
+        entry = gtk_bin_get_child (GTK_BIN (priv->combo));
+        /* Longest name + two digits + % + icon(3) */
+        gtk_entry_set_width_chars (GTK_ENTRY (entry),
+                                   strlen (zoom_levels[G_N_ELEMENTS (zoom_levels) - 1].name) + 3 + 3);
+
+        renderer = gtk_cell_renderer_text_new ();
+        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->combo), renderer, FALSE);
+        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->combo), renderer,
+                                        "text", TEXT_COLUMN, NULL);
+        gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (priv->combo),
+                                              (GtkTreeViewRowSeparatorFunc)row_is_separator,
+                                              NULL, NULL);
+
+        vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+        gtk_box_pack_start (GTK_BOX (vbox), priv->combo, TRUE, FALSE, 0);
+        gtk_widget_show (priv->combo);
+
+        gtk_container_add (GTK_CONTAINER (control), vbox);
+        gtk_widget_show (vbox);
+
+        priv->combo_changed_handler =
+                g_signal_connect (priv->combo, "changed",
+                                  G_CALLBACK (combo_changed_cb),
+                                  control);
+        g_signal_connect (priv->combo, "format-entry-text",
+                          G_CALLBACK (combo_format_entry_text),
+                          control);
+        g_signal_connect (entry, "activate",
+                          G_CALLBACK (combo_activated_cb),
+                          control);
+}
+
+static void
+ev_zoom_action_widget_class_init (EvZoomActionWidgetClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->finalize = ev_zoom_action_widget_finalize;
+
+        g_type_class_add_private (object_class, sizeof (EvZoomActionWidgetPrivate));
+}
+
+void
+ev_zoom_action_widget_set_model (EvZoomActionWidget *control,
+                                 EvDocumentModel    *model)
+{
+        g_return_if_fail (EV_IS_ZOOM_ACTION_WIDGET (control));
+
+        if (control->priv->model == model)
+                return;
+
+        if (control->priv->model) {
+                g_object_remove_weak_pointer (G_OBJECT (control->priv->model),
+                                              (gpointer)&control->priv->model);
+                g_signal_handlers_disconnect_by_func (control->priv->model,
+                                                      G_CALLBACK (zoom_changed_cb),
+                                                      control);
+                g_signal_handlers_disconnect_by_func (control->priv->model,
+                                                      G_CALLBACK (sizing_mode_changed_cb),
+                                                      control);
+        }
+        control->priv->model = model;
+        if (!model)
+                return;
+
+        g_object_add_weak_pointer (G_OBJECT (model),
+                                   (gpointer)&control->priv->model);
+
+        if (ev_document_model_get_document (model)) {
+                ev_zoom_action_widget_update_zoom_level (control);
+                ev_zoom_action_widget_update_sizing_mode (control);
+        } else {
+                ev_zoom_action_widget_set_zoom_level (control, 1.);
+        }
+
+        g_signal_connect (control->priv->model, "notify::document",
+                          G_CALLBACK (document_changed_cb),
+                          control);
+        g_signal_connect (control->priv->model, "notify::scale",
+                          G_CALLBACK (zoom_changed_cb),
+                          control);
+        g_signal_connect (control->priv->model, "notify::sizing-mode",
+                          G_CALLBACK (sizing_mode_changed_cb),
+                          control);
+}
+
+void
+ev_zoom_action_widget_set_max_zoom_level (EvZoomActionWidget *control,
+                                          float               max_zoom)
+{
+        EvZoomActionWidgetPrivate *priv;
+        GtkListStore              *model;
+        guint                      max_level_index = 3;
+        guint                      i;
+
+        g_return_if_fail (EV_IS_ZOOM_ACTION_WIDGET (control));
+
+        priv = control->priv;
+
+        for (i = 3; i < G_N_ELEMENTS (zoom_levels); i++, max_level_index++) {
+                if (zoom_levels[i].level > max_zoom)
+                        break;
+        }
+
+        g_signal_handler_block (priv->combo, priv->combo_changed_handler);
+
+        model = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (priv->combo)));
+        gtk_list_store_clear (model);
+        fill_combo_model (model, max_level_index);
+
+        g_signal_handler_unblock (priv->combo, priv->combo_changed_handler);
+}
+
+GtkWidget *
+ev_zoom_action_widget_get_combo_box (EvZoomActionWidget *control)
+{
+        g_return_val_if_fail (EV_IS_ZOOM_ACTION_WIDGET (control), NULL);
+
+        return control->priv->combo;
+}
diff --git a/shell/ev-zoom-action-widget.h b/shell/ev-zoom-action-widget.h
new file mode 100644
index 0000000..c42c7d3
--- /dev/null
+++ b/shell/ev-zoom-action-widget.h
@@ -0,0 +1,61 @@
+/* ev-zoom-action-widget.h
+ *  this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2012 Carlos Garcia Campos  <carlosgc gnome org>
+ *
+ * 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_ZOOM_ACTION_WIDGET_H
+#define EV_ZOOM_ACTION_WIDGET_H
+
+#include <gtk/gtk.h>
+#include <evince-document.h>
+#include <evince-view.h>
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_ZOOM_ACTION_WIDGET            (ev_zoom_action_widget_get_type())
+#define EV_ZOOM_ACTION_WIDGET(object)         (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_ZOOM_ACTION_WIDGET, EvZoomActionWidget))
+#define EV_IS_ZOOM_ACTION_WIDGET(object)      (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_ZOOM_ACTION_WIDGET))
+#define EV_ZOOM_ACTION_WIDGET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_ZOOM_ACTION_WIDGET, EvZoomActionWidgetClass))
+#define EV_IS_ZOOM_ACTION_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_ZOOM_ACTION_WIDGET))
+#define EV_ZOOM_ACTION_WIDGET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), EV_TYPE_ZOOM_ACTION_WIDGET, EvZoomActionWidgetClass))
+
+typedef struct _EvZoomActionWidget        EvZoomActionWidget;
+typedef struct _EvZoomActionWidgetClass   EvZoomActionWidgetClass;
+typedef struct _EvZoomActionWidgetPrivate EvZoomActionWidgetPrivate;
+
+struct _EvZoomActionWidget {
+        GtkToolItem parent_object;
+
+        EvZoomActionWidgetPrivate *priv;
+};
+
+struct _EvZoomActionWidgetClass {
+        GtkToolItemClass parent_class;
+};
+
+GType      ev_zoom_action_widget_get_type           (void);
+
+void       ev_zoom_action_widget_set_model          (EvZoomActionWidget *control,
+                                                     EvDocumentModel    *model);
+GtkWidget *ev_zoom_action_widget_get_combo_box      (EvZoomActionWidget *control);
+void       ev_zoom_action_widget_set_max_zoom_level (EvZoomActionWidget *control,
+                                                     float               max_zoom);
+
+G_END_DECLS
+
+#endif
diff --git a/shell/ev-zoom-action.c b/shell/ev-zoom-action.c
new file mode 100644
index 0000000..f75d853
--- /dev/null
+++ b/shell/ev-zoom-action.c
@@ -0,0 +1,152 @@
+/* ev-zoom-action.c
+ *  this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2012 Carlos Garcia Campos  <carlosgc gnome org>
+ *
+ * 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-zoom-action.h"
+#include "ev-zoom-action-widget.h"
+
+enum {
+        ACTIVATED,
+        LAST_SIGNAL
+};
+
+
+struct _EvZoomActionPrivate {
+        EvDocumentModel *model;
+        gboolean         popup_shown;
+        float            max_zoom;
+};
+
+G_DEFINE_TYPE (EvZoomAction, ev_zoom_action, GTK_TYPE_ACTION)
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+popup_shown_cb (GObject      *combo,
+                GParamSpec   *pspec,
+                EvZoomAction *zoom_action)
+{
+        g_object_get (combo, "popup-shown", &zoom_action->priv->popup_shown, NULL);
+}
+
+static void
+zoom_widget_activated_cb (GtkEntry     *entry,
+                          EvZoomAction *zoom_action)
+{
+        g_signal_emit (zoom_action, signals[ACTIVATED], 0, NULL);
+}
+
+static void
+connect_proxy (GtkAction *action,
+               GtkWidget *proxy)
+{
+        if (EV_IS_ZOOM_ACTION_WIDGET (proxy))   {
+                EvZoomAction *zoom_action = EV_ZOOM_ACTION (action);
+                EvZoomActionWidget* zoom_widget = EV_ZOOM_ACTION_WIDGET (proxy);
+                GtkWidget *combo;
+
+                ev_zoom_action_widget_set_model (zoom_widget, zoom_action->priv->model);
+                ev_zoom_action_widget_set_max_zoom_level (zoom_widget, zoom_action->priv->max_zoom);
+
+                combo = ev_zoom_action_widget_get_combo_box (zoom_widget);
+                g_signal_connect (combo, "notify::popup-shown",
+                                  G_CALLBACK (popup_shown_cb),
+                                  action);
+                g_signal_connect (gtk_bin_get_child (GTK_BIN (combo)), "activate",
+                                  G_CALLBACK (zoom_widget_activated_cb),
+                                  action);
+        }
+
+        GTK_ACTION_CLASS (ev_zoom_action_parent_class)->connect_proxy (action, proxy);
+}
+
+static void
+ev_zoom_action_class_init (EvZoomActionClass *class)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (class);
+        GtkActionClass *action_class = GTK_ACTION_CLASS (class);
+
+        action_class->toolbar_item_type = EV_TYPE_ZOOM_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 (EvZoomActionPrivate));
+}
+
+static void
+ev_zoom_action_init (EvZoomAction *action)
+{
+        action->priv = G_TYPE_INSTANCE_GET_PRIVATE (action, EV_TYPE_ZOOM_ACTION, EvZoomActionPrivate);
+}
+
+void
+ev_zoom_action_set_model (EvZoomAction    *action,
+                          EvDocumentModel *model)
+{
+        GSList *proxies, *l;
+
+        g_return_if_fail (EV_IS_ZOOM_ACTION (action));
+        g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
+
+        if (action->priv->model == model)
+                return;
+
+        action->priv->model = model;
+        proxies = gtk_action_get_proxies (GTK_ACTION (action));
+        for (l = proxies; l && l->data; l = g_slist_next (l)) {
+                if (EV_IS_ZOOM_ACTION_WIDGET (l->data))
+                        ev_zoom_action_widget_set_model (EV_ZOOM_ACTION_WIDGET (l->data), model);
+        }
+}
+
+gboolean
+ev_zoom_action_get_popup_shown (EvZoomAction *action)
+{
+        g_return_val_if_fail (EV_IS_ZOOM_ACTION (action), FALSE);
+
+        return action->priv->popup_shown;
+}
+
+void
+ev_zoom_action_set_max_zoom_level (EvZoomAction *action,
+                                   float         max_zoom)
+{
+        GSList *proxies, *l;
+
+        g_return_if_fail (EV_IS_ZOOM_ACTION (action));
+
+        if (action->priv->max_zoom == max_zoom)
+                return;
+
+        action->priv->max_zoom = max_zoom;
+        proxies = gtk_action_get_proxies (GTK_ACTION (action));
+        for (l = proxies; l && l->data; l = g_slist_next (l)) {
+                if (EV_IS_ZOOM_ACTION_WIDGET (l->data))
+                        ev_zoom_action_widget_set_max_zoom_level (EV_ZOOM_ACTION_WIDGET (l->data), max_zoom);
+        }
+}
diff --git a/shell/ev-zoom-action.h b/shell/ev-zoom-action.h
new file mode 100644
index 0000000..4ef66fe
--- /dev/null
+++ b/shell/ev-zoom-action.h
@@ -0,0 +1,61 @@
+/* ev-zoom-action.h
+ *  this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2012 Carlos Garcia Campos  <carlosgc gnome org>
+ *
+ * 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_ZOOM_ACTION_H
+#define EV_ZOOM_ACTION_H
+
+#include <gtk/gtk.h>
+#include <evince-document.h>
+#include <evince-view.h>
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_ZOOM_ACTION            (ev_zoom_action_get_type ())
+#define EV_ZOOM_ACTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_ZOOM_ACTION, EvZoomAction))
+#define EV_IS_ZOOM_ACTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_ZOOM_ACTION))
+#define EV_ZOOM_ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_ZOOM_ACTION, EvZoomActionClass))
+#define EV_IS_ZOOM_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EV_TYPE_ZOOM_ACTION))
+#define EV_ZOOM_ACTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), EV_TYPE_ZOOM_ACTION, EvZoomActionClass))
+
+typedef struct _EvZoomAction        EvZoomAction;
+typedef struct _EvZoomActionClass   EvZoomActionClass;
+typedef struct _EvZoomActionPrivate EvZoomActionPrivate;
+
+struct _EvZoomAction {
+        GtkAction parent;
+
+        EvZoomActionPrivate *priv;
+};
+
+struct _EvZoomActionClass {
+        GtkActionClass parent_class;
+};
+
+GType    ev_zoom_action_get_type           (void);
+
+void     ev_zoom_action_set_model          (EvZoomAction    *action,
+                                            EvDocumentModel *model);
+gboolean ev_zoom_action_get_popup_shown    (EvZoomAction    *action);
+void     ev_zoom_action_set_max_zoom_level (EvZoomAction    *action,
+                                            float            max_zoom);
+
+G_END_DECLS
+
+#endif



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