[evince] Use GMenu for the zoom selector instead of GtkAction
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince] Use GMenu for the zoom selector instead of GtkAction
- Date: Sat, 21 Jun 2014 09:35:18 +0000 (UTC)
commit 55b21fe75eb910992af06a23fdd11d3073c06f6e
Author: Carlos Garcia Campos <carlosgc gnome org>
Date: Sat Jun 21 11:33:24 2014 +0200
Use GMenu for the zoom selector instead of GtkAction
Merge EvZoomAction and EvZoomActionWidget into a single widget
derived from GtkBox that uses GAction.
po/POTFILES.in | 1 +
shell/Makefile.am | 2 -
shell/ev-toolbar.c | 28 ++-
shell/ev-window.c | 230 +++----------------
shell/ev-window.h | 4 +-
shell/ev-zoom-action-widget.c | 429 ----------------------------------
shell/ev-zoom-action-widget.h | 63 -----
shell/ev-zoom-action.c | 506 ++++++++++++++++++++++++++++++++++++-----
shell/ev-zoom-action.h | 36 +---
shell/evince-menus.ui | 24 ++
shell/evince-ui.xml | 8 -
11 files changed, 529 insertions(+), 802 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 86c7443..d94d468 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -52,6 +52,7 @@ shell/ev-toolbar.c
shell/ev-utils.c
shell/ev-window.c
shell/ev-window-title.c
+shell/ev-zoom-action.c
shell/main.c
[type: gettext/glade]shell/evince-menus.ui
evince.appdata.xml.in
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 5024554..63dc48d 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -55,8 +55,6 @@ evince_SOURCES= \
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-toolbar.c b/shell/ev-toolbar.c
index 5e7278c..6b68dee 100644
--- a/shell/ev-toolbar.c
+++ b/shell/ev-toolbar.c
@@ -45,6 +45,7 @@ struct _EvToolbarPrivate {
GtkWidget *view_menu_button;
GtkWidget *action_menu_button;
GtkWidget *history_action;
+ GtkWidget *zoom_action;
GMenu *bookmarks_section;
};
@@ -182,13 +183,20 @@ ev_toolbar_bookmarks_menu_model_changed (GMenuModel *model,
}
static void
+zoom_selector_activated (GtkWidget *zoom_action,
+ EvToolbar *toolbar)
+{
+ ev_window_focus_view (toolbar->priv->window);
+}
+
+static void
ev_toolbar_constructed (GObject *object)
{
EvToolbar *ev_toolbar = EV_TOOLBAR (object);
GtkBuilder *builder;
GtkActionGroup *action_group;
GtkWidget *tool_item;
- GtkWidget *hbox;
+ GtkWidget *hbox, *vbox;
GtkAction *action;
GtkWidget *button;
gboolean rtl;
@@ -277,12 +285,20 @@ ev_toolbar_constructed (GObject *object)
gtk_widget_show (tool_item);
/* Zoom selector */
- action = gtk_action_group_get_action (action_group, "ViewZoom");
- tool_item = gtk_action_create_tool_item (action);
+ vbox = ev_zoom_action_new (ev_window_get_document_model (ev_toolbar->priv->window),
+ G_MENU (gtk_builder_get_object (builder, "zoom-menu")));
+ ev_toolbar->priv->zoom_action = vbox;
+ g_signal_connect (vbox, "activated",
+ G_CALLBACK (zoom_selector_activated),
+ ev_toolbar);
+ 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), vbox);
+ gtk_widget_show (vbox);
+
gtk_container_add (GTK_CONTAINER (ev_toolbar), tool_item);
gtk_widget_show (tool_item);
@@ -374,8 +390,6 @@ ev_toolbar_new (EvWindow *window)
gboolean
ev_toolbar_has_visible_popups (EvToolbar *ev_toolbar)
{
- GtkAction *action;
- GtkActionGroup *action_group;
GtkMenu *popup_menu;
EvToolbarPrivate *priv;
@@ -391,9 +405,7 @@ ev_toolbar_has_visible_popups (EvToolbar *ev_toolbar)
if (gtk_widget_get_visible (GTK_WIDGET (popup_menu)))
return TRUE;
- action_group = ev_window_get_main_action_group (ev_toolbar->priv->window);
- action = gtk_action_group_get_action (action_group, "ViewZoom");
- if (ev_zoom_action_get_popup_shown (EV_ZOOM_ACTION (action)))
+ if (ev_zoom_action_get_popup_shown (EV_ZOOM_ACTION (ev_toolbar->priv->zoom_action)))
return TRUE;
if (ev_history_action_get_popup_shown (EV_HISTORY_ACTION (ev_toolbar->priv->history_action)))
diff --git a/shell/ev-window.c b/shell/ev-window.c
index ac9868a..9355e61 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -171,7 +171,6 @@ struct _EvWindowPrivate {
GtkActionGroup *action_group;
GtkActionGroup *view_popup_action_group;
GtkActionGroup *attachment_popup_action_group;
- GtkActionGroup *zoom_selector_popup_action_group;
GtkRecentManager *recent_manager;
guint bookmarks_ui_id;
GtkUIManager *ui_manager;
@@ -241,7 +240,6 @@ struct _EvWindowPrivate {
#define EV_WINDOW_IS_PRESENTATION(w) (w->priv->presentation_view != NULL)
#define PAGE_SELECTOR_ACTION "PageSelector"
-#define ZOOM_CONTROL_ACTION "ViewZoom"
#define GS_LOCKDOWN_SCHEMA_NAME "org.gnome.desktop.lockdown"
#define GS_LOCKDOWN_SAVE "disable-save-to-disk"
@@ -341,12 +339,6 @@ static void ev_attachment_popup_cmd_open_attachment (GtkAction *action,
EvWindow *window);
static void ev_attachment_popup_cmd_save_attachment_as (GtkAction *action,
EvWindow *window);
-static void ev_window_cmd_view_fit_page (GtkAction *action,
- EvWindow *ev_window);
-static void ev_window_cmd_view_fit_width (GtkAction *action,
- EvWindow *ev_window);
-static void ev_window_cmd_view_zoom_automatic (GtkAction *action,
- EvWindow *ev_window);
static void view_handle_link_cb (EvView *view,
EvLink *link,
EvWindow *window);
@@ -492,7 +484,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_update_actions_sensitivity (ev_window);
}
@@ -610,46 +601,27 @@ update_chrome_flag (EvWindow *window, EvChrome flag, gboolean active)
static void
update_sizing_buttons (EvWindow *window)
{
- GtkActionGroup *action_group = window->priv->zoom_selector_popup_action_group;
- GtkAction *action;
- gboolean fit_page = FALSE;
- gboolean fit_width = FALSE;
- gboolean automatic = FALSE;
+ GAction *action;
+ const gchar *mode = NULL;
+
+ action = g_action_map_lookup_action (G_ACTION_MAP (window), "sizing-mode");
switch (ev_document_model_get_sizing_mode (window->priv->model)) {
case EV_SIZING_FIT_PAGE:
- fit_page = TRUE;
+ mode = "fit-page";
break;
case EV_SIZING_FIT_WIDTH:
- fit_width = TRUE;
+ mode = "fit-width";
break;
case EV_SIZING_AUTOMATIC:
- automatic = TRUE;
+ mode = "automatic";
break;
case EV_SIZING_FREE:
+ mode = "free";
break;
}
- action = gtk_action_group_get_action (action_group, "ViewFitPage");
- g_signal_handlers_block_by_func
- (action, G_CALLBACK (ev_window_cmd_view_fit_page), window);
- gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), fit_page);
- g_signal_handlers_unblock_by_func
- (action, G_CALLBACK (ev_window_cmd_view_fit_page), window);
-
- action = gtk_action_group_get_action (action_group, "ViewFitWidth");
- g_signal_handlers_block_by_func
- (action, G_CALLBACK (ev_window_cmd_view_fit_width), window);
- gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), fit_width);
- g_signal_handlers_unblock_by_func
- (action, G_CALLBACK (ev_window_cmd_view_fit_width), window);
-
- action = gtk_action_group_get_action (action_group, "ViewZoomAutomatic");
- g_signal_handlers_block_by_func
- (action, G_CALLBACK (ev_window_cmd_view_zoom_automatic), window);
- gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), automatic);
- g_signal_handlers_unblock_by_func
- (action, G_CALLBACK (ev_window_cmd_view_zoom_automatic), window);
+ g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_string (mode));
}
/**
@@ -3747,19 +3719,6 @@ ev_window_cmd_dual_odd_pages_left (GSimpleAction *action,
}
static void
-ev_window_cmd_view_fit_page (GtkAction *action, EvWindow *ev_window)
-{
- ev_window_stop_presentation (ev_window, TRUE);
-
- if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
- ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FIT_PAGE);
- } else {
- ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE);
- }
- ev_window_update_actions_sensitivity (ev_window);
-}
-
-static void
ev_window_change_sizing_mode_action_state (GSimpleAction *action,
GVariant *state,
gpointer user_data)
@@ -3784,47 +3743,12 @@ ev_window_change_sizing_mode_action_state (GSimpleAction *action,
}
static void
-ev_window_cmd_view_fit_width (GtkAction *action, EvWindow *ev_window)
-{
- ev_window_stop_presentation (ev_window, TRUE);
-
- if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
- ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FIT_WIDTH);
- } else {
- ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE);
- }
- ev_window_update_actions_sensitivity (ev_window);
-}
-
-static void
-ev_window_cmd_view_zoom_automatic (GtkAction *action,
- EvWindow *ev_window)
-{
- ev_window_stop_presentation (ev_window, TRUE);
-
- if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
- ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_AUTOMATIC);
- } else {
- ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE);
- }
- ev_window_update_actions_sensitivity (ev_window);
-}
-
-static void
-ev_window_cmd_view_zoom_activate (GtkAction *action,
- EvWindow *ev_window)
+ev_window_cmd_view_zoom (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
{
- const char *action_name = gtk_action_get_name (action);
- gdouble zoom = 0;
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++) {
- if (strcmp (action_name, zoom_levels[i].name) == 0) {
- zoom = zoom_levels[i].level;
- break;
- }
- }
- g_assert (zoom > 0);
+ EvWindow *ev_window = user_data;
+ gdouble zoom = g_variant_get_double (parameter);
ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE);
ev_document_model_set_scale (ev_window->priv->model,
@@ -4764,27 +4688,6 @@ ev_window_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *
}
static void
-ev_window_setup_zoom_actions_visibility (EvWindow *window,
- gdouble max_scale)
-{
- GtkActionGroup *action_group = window->priv->zoom_selector_popup_action_group;
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++) {
- GtkAction *action;
-
- action = gtk_action_group_get_action (action_group, zoom_levels[i].name);
- gtk_action_set_visible (action, zoom_levels[i].level <= max_scale);
- }
-}
-
-static void
-ev_window_max_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *window)
-{
- ev_window_setup_zoom_actions_visibility (window, ev_document_model_get_max_scale (model));
-}
-
-static void
ev_window_continuous_changed_cb (EvDocumentModel *model,
GParamSpec *pspec,
EvWindow *ev_window)
@@ -5565,8 +5468,6 @@ ev_window_dispose (GObject *object)
priv->attachment_popup_action_group = NULL;
}
- g_clear_object (&priv->zoom_selector_popup_action_group);
-
g_clear_object (&priv->bookmarks_menu);
if (priv->recent_manager) {
@@ -5804,6 +5705,7 @@ static const GActionEntry actions[] = {
{ "scroll-forward", ev_window_cmd_scroll_forward },
{ "scroll-backwards", ev_window_cmd_scroll_backwards },
{ "sizing-mode", NULL, "s", "'free'", ev_window_change_sizing_mode_action_state },
+ { "zoom", ev_window_cmd_view_zoom, "d" },
{ "escape", ev_window_cmd_escape },
{ "open-menu", ev_window_cmd_action_menu },
{ "caret-navigation", NULL, NULL, "false", ev_window_cmd_view_toggle_caret_navigation },
@@ -5835,17 +5737,6 @@ static const GtkActionEntry attachment_popup_entries [] = {
NULL, G_CALLBACK (ev_attachment_popup_cmd_save_attachment_as) },
};
-static const GtkToggleActionEntry zoom_selector_popup_actions[] = {
- { "ViewFitPage", EV_STOCK_ZOOM_PAGE, N_("Fit Pa_ge"), NULL,
- N_("Make the current document fill the window"),
- G_CALLBACK (ev_window_cmd_view_fit_page) },
- { "ViewFitWidth", EV_STOCK_ZOOM_WIDTH, N_("Fit _Width"), NULL,
- N_("Make the current document fill the window width"),
- G_CALLBACK (ev_window_cmd_view_fit_width) },
- { "ViewZoomAutomatic", NULL, N_("_Automatic"), NULL, NULL,
- G_CALLBACK (ev_window_cmd_view_zoom_automatic) }
-};
-
static void
sidebar_links_link_activated_cb (EvSidebarLinks *sidebar_links, EvLink *link, EvWindow *window)
{
@@ -5909,43 +5800,6 @@ sidebar_annots_annot_add_cancelled (EvSidebarAnnotations *sidebar_annots,
}
static void
-zoom_action_activated_cb (EvZoomAction *action,
- EvWindow *window)
-{
- gtk_widget_grab_focus (window->priv->view);
-}
-
-static void
-ev_window_register_zoom_selector_popup_actions (EvWindow *window)
-{
- GtkActionGroup *action_group = window->priv->zoom_selector_popup_action_group;
- guint i, new_ui_id;
-
- new_ui_id = gtk_ui_manager_new_merge_id (window->priv->ui_manager);
-
- for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++) {
- GtkAction *action;
-
- action = gtk_action_new (zoom_levels[i].name,
- _(zoom_levels[i].name),
- NULL, NULL);
- g_signal_connect (action, "activate",
- G_CALLBACK (ev_window_cmd_view_zoom_activate),
- window);
- gtk_action_group_add_action (action_group, action);
- g_object_unref (action);
-
- gtk_ui_manager_add_ui (window->priv->ui_manager,
- new_ui_id,
- "/ZoomSelectorPopup/ViewZoomItems",
- _(zoom_levels[i].name),
- zoom_levels[i].name,
- GTK_UI_MANAGER_MENUITEM,
- FALSE);
- }
-}
-
-static void
register_custom_actions (EvWindow *window, GtkActionGroup *group)
{
GtkAction *action;
@@ -5963,21 +5817,6 @@ register_custom_actions (EvWindow *window, GtkActionGroup *group)
G_CALLBACK (activate_link_cb), window);
gtk_action_group_add_action (group, action);
g_object_unref (action);
-
- action = g_object_new (EV_TYPE_ZOOM_ACTION,
- "name", ZOOM_CONTROL_ACTION,
- "label", _("Zoom"),
- "stock_id", EV_STOCK_ZOOM,
- "tooltip", _("Adjust the zoom level"),
- NULL);
- ev_zoom_action_set_model (EV_ZOOM_ACTION (action),
- window->priv->model);
- ev_zoom_action_set_window (EV_ZOOM_ACTION (action),
- window);
- g_signal_connect (action, "activated",
- G_CALLBACK (zoom_action_activated_cb), window);
- gtk_action_group_add_action (group, action);
- g_object_unref (action);
}
static void
@@ -6958,22 +6797,11 @@ ev_window_init (EvWindow *ev_window)
gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
action_group, 0);
- action_group = gtk_action_group_new ("ZoomSelectorPopupActions");
- ev_window->priv->zoom_selector_popup_action_group = action_group;
- gtk_action_group_set_translation_domain (action_group, NULL);
- gtk_action_group_add_toggle_actions (action_group, zoom_selector_popup_actions,
- G_N_ELEMENTS (zoom_selector_popup_actions),
- ev_window);
- gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
- action_group, 0);
-
gtk_ui_manager_add_ui_from_resource (ev_window->priv->ui_manager,
"/org/gnome/evince/shell/ui/evince.xml",
&error);
g_assert_no_error (error);
- ev_window_register_zoom_selector_popup_actions (ev_window);
-
css_provider = gtk_css_provider_new ();
_gtk_css_provider_load_from_resource (css_provider,
"/org/gnome/evince/shell/ui/evince.css",
@@ -7195,10 +7023,6 @@ ev_window_init (EvWindow *ev_window)
G_CALLBACK (ev_window_zoom_changed_cb),
ev_window);
g_signal_connect (ev_window->priv->model,
- "notify::max-scale",
- G_CALLBACK (ev_window_max_zoom_changed_cb),
- ev_window);
- g_signal_connect (ev_window->priv->model,
"notify::sizing-mode",
G_CALLBACK (ev_window_sizing_mode_changed_cb),
ev_window);
@@ -7348,14 +7172,6 @@ ev_window_get_main_action_group (EvWindow *ev_window)
return ev_window->priv->action_group;
}
-GtkActionGroup *
-ev_window_get_zoom_selector_action_group (EvWindow *ev_window)
-{
- g_return_val_if_fail (EV_WINDOW (ev_window), NULL);
-
- return ev_window->priv->zoom_selector_popup_action_group;
-}
-
GMenuModel *
ev_window_get_bookmarks_menu (EvWindow *ev_window)
{
@@ -7371,3 +7187,19 @@ ev_window_get_history (EvWindow *ev_window)
return ev_window->priv->history;
}
+
+EvDocumentModel *
+ev_window_get_document_model (EvWindow *ev_window)
+{
+ g_return_val_if_fail (EV_WINDOW (ev_window), NULL);
+
+ return ev_window->priv->model;
+}
+
+void
+ev_window_focus_view (EvWindow *ev_window)
+{
+ g_return_if_fail (EV_WINDOW (ev_window));
+
+ gtk_widget_grab_focus (ev_window->priv->view);
+}
diff --git a/shell/ev-window.h b/shell/ev-window.h
index d074073..cabd9c9 100644
--- a/shell/ev-window.h
+++ b/shell/ev-window.h
@@ -28,6 +28,7 @@
#include "ev-link.h"
#include "ev-history.h"
+#include "ev-document-model.h"
G_BEGIN_DECLS
@@ -89,9 +90,10 @@ void ev_window_print_range (EvWindow *ev_window,
const gchar *ev_window_get_dbus_object_path (EvWindow *ev_window);
GtkUIManager *ev_window_get_ui_manager (EvWindow *ev_window);
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);
+EvDocumentModel *ev_window_get_document_model (EvWindow *ev_window);
+void ev_window_focus_view (EvWindow *ev_window);
G_END_DECLS
diff --git a/shell/ev-zoom-action.c b/shell/ev-zoom-action.c
index 2e974d7..86b1929 100644
--- a/shell/ev-zoom-action.c
+++ b/shell/ev-zoom-action.c
@@ -19,70 +19,458 @@
*/
#include "config.h"
-
#include "ev-zoom-action.h"
-#include "ev-zoom-action-widget.h"
+
+#include <glib/gi18n.h>
enum {
ACTIVATED,
LAST_SIGNAL
};
+enum
+{
+ PROP_0,
+
+ PROP_DOCUMENT_MODEL,
+ PROP_MENU
+};
+
+enum {
+ ZOOM_MODES_SECTION,
+ ZOOM_FREE_SECTION
+};
+
+static const struct {
+ const gchar *name;
+ float level;
+} zoom_levels[] = {
+ { 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 }
+};
struct _EvZoomActionPrivate {
+ GtkWidget *entry;
+
EvDocumentModel *model;
- EvWindow *window;
+ GMenu *menu;
+
+ GMenuModel *zoom_free_section;
+ GtkWidget *popup;
gboolean popup_shown;
};
-G_DEFINE_TYPE (EvZoomAction, ev_zoom_action, GTK_TYPE_ACTION)
+G_DEFINE_TYPE (EvZoomAction, ev_zoom_action, GTK_TYPE_BOX)
static guint signals[LAST_SIGNAL] = { 0 };
+#define EPSILON 0.000001
+
+static void
+ev_zoom_action_set_zoom_level (EvZoomAction *zoom_action,
+ float zoom)
+{
+ 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 (zoom_action->priv->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 (zoom_action->priv->entry), zoom_str);
+ g_free (zoom_str);
+}
+
+static void
+ev_zoom_action_update_zoom_level (EvZoomAction *zoom_action)
+{
+ float zoom = ev_document_model_get_scale (zoom_action->priv->model);
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (zoom_action));
+
+ zoom *= 72.0 / ev_document_misc_get_screen_dpi (screen);
+ ev_zoom_action_set_zoom_level (zoom_action, zoom);
+}
+
+static void
+zoom_changed_cb (EvDocumentModel *model,
+ GParamSpec *pspec,
+ EvZoomAction *zoom_action)
+{
+ ev_zoom_action_update_zoom_level (zoom_action);
+}
+
+static void
+document_changed_cb (EvDocumentModel *model,
+ GParamSpec *pspec,
+ EvZoomAction *zoom_action)
+{
+ EvDocument *document = ev_document_model_get_document (model);
+
+ if (!document) {
+ gtk_widget_set_sensitive (GTK_WIDGET (zoom_action), FALSE);
+ return;
+ }
+ gtk_widget_set_sensitive (GTK_WIDGET (zoom_action), ev_document_get_n_pages (document) > 0);
+
+ ev_zoom_action_update_zoom_level (zoom_action);
+}
+
+static void
+ev_zoom_action_populate_free_zoom_section (EvZoomAction *zoom_action)
+{
+ gdouble max_scale;
+ guint i;
+
+ max_scale = ev_document_model_get_max_scale (zoom_action->priv->model);
+
+ for (i = 0; i < G_N_ELEMENTS (zoom_levels); i++) {
+ GMenuItem *item;
+
+ if (zoom_levels[i].level > max_scale)
+ break;
+
+ item = g_menu_item_new (zoom_levels[i].name, NULL);
+ g_menu_item_set_action_and_target (item, "win.zoom",
+ "d", zoom_levels[i].level);
+ g_menu_append_item (G_MENU (zoom_action->priv->zoom_free_section), item);
+ g_object_unref (item);
+ }
+}
+
static void
-popup_shown_cb (GObject *zoom_widget,
- GParamSpec *pspec,
- EvZoomAction *zoom_action)
+max_zoom_changed_cb (EvDocumentModel *model,
+ GParamSpec *pspec,
+ EvZoomAction *zoom_action)
{
- g_object_get (zoom_widget, "popup-shown", &zoom_action->priv->popup_shown, NULL);
+ g_menu_remove_all (G_MENU (zoom_action->priv->zoom_free_section));
+ g_clear_pointer (&zoom_action->priv->popup, (GDestroyNotify)gtk_widget_destroy);
+ ev_zoom_action_populate_free_zoom_section (zoom_action);
}
static void
-zoom_widget_activated_cb (GtkEntry *entry,
- EvZoomAction *zoom_action)
+entry_activated_cb (GtkEntry *entry,
+ EvZoomAction *zoom_action)
{
+ 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_update_zoom_level (zoom_action);
+ g_signal_emit (zoom_action, signals[ACTIVATED], 0, NULL);
+ return;
+ }
+
+ zoom_perc = g_strtod (text, &end_ptr);
+ if (end_ptr && end_ptr[0] != '\0' && end_ptr[0] != '%') {
+ ev_zoom_action_update_zoom_level (zoom_action);
+ g_signal_emit (zoom_action, signals[ACTIVATED], 0, NULL);
+ return;
+ }
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (zoom_action));
+ zoom = zoom_perc / 100.;
+ ev_document_model_set_sizing_mode (zoom_action->priv->model, EV_SIZING_FREE);
+ ev_document_model_set_scale (zoom_action->priv->model,
+ zoom * ev_document_misc_get_screen_dpi (screen) / 72.0);
g_signal_emit (zoom_action, signals[ACTIVATED], 0, NULL);
}
+static gboolean
+focus_out_cb (EvZoomAction *zoom_action)
+{
+ ev_zoom_action_update_zoom_level (zoom_action);
+
+ return FALSE;
+}
+
+static void
+popup_menu_show_cb (GtkWidget *widget,
+ EvZoomAction *zoom_action)
+{
+ zoom_action->priv->popup_shown = TRUE;
+}
+
+static void
+popup_menu_hide_cb (GtkWidget *widget,
+ EvZoomAction *zoom_action)
+{
+ zoom_action->priv->popup_shown = FALSE;
+}
+
+static void
+popup_menu_detached (EvZoomAction *zoom_action,
+ GtkWidget *popup)
+{
+ GtkWidget *toplevel;
+
+ if (zoom_action->priv->popup != popup)
+ return;
+
+ toplevel = gtk_widget_get_toplevel (zoom_action->priv->popup);
+ g_signal_handlers_disconnect_by_func (toplevel,
+ popup_menu_show_cb,
+ zoom_action);
+ g_signal_handlers_disconnect_by_func (toplevel,
+ popup_menu_hide_cb,
+ zoom_action);
+
+ zoom_action->priv->popup = NULL;
+}
+
+static GtkWidget *
+get_popup (EvZoomAction *zoom_action)
+{
+ GtkWidget *toplevel;
+
+ if (zoom_action->priv->popup)
+ return zoom_action->priv->popup;
+
+ zoom_action->priv->popup = gtk_menu_new_from_model (G_MENU_MODEL (zoom_action->priv->menu));
+ gtk_menu_attach_to_widget (GTK_MENU (zoom_action->priv->popup),
+ GTK_WIDGET (zoom_action),
+ (GtkMenuDetachFunc)popup_menu_detached);
+ toplevel = gtk_widget_get_toplevel (zoom_action->priv->popup);
+ g_signal_connect (toplevel, "show",
+ G_CALLBACK (popup_menu_show_cb),
+ zoom_action);
+ g_signal_connect (toplevel, "hide",
+ G_CALLBACK (popup_menu_hide_cb),
+ zoom_action);
+
+ return zoom_action->priv->popup;
+}
+
+
+static void
+menu_position_below (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gint *push_in,
+ gpointer user_data)
+{
+ EvZoomAction *zoom_action;
+ GtkWidget *widget;
+ GtkAllocation child_allocation;
+ GtkRequisition req;
+ GdkScreen *screen;
+ gint monitor_num;
+ GdkRectangle monitor;
+ gint sx = 0, sy = 0;
+
+ zoom_action = EV_ZOOM_ACTION (user_data);
+ widget = GTK_WIDGET (zoom_action);
+
+ gtk_widget_get_allocation (zoom_action->priv->entry, &child_allocation);
+
+ if (!gtk_widget_get_has_window (zoom_action->priv->entry)) {
+ sx += child_allocation.x;
+ sy += child_allocation.y;
+ }
+
+ gdk_window_get_root_coords (gtk_widget_get_window (zoom_action->priv->entry),
+ sx, sy, &sx, &sy);
+
+ gtk_widget_get_preferred_size (GTK_WIDGET (menu), &req, NULL);
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ *x = sx;
+ else
+ *x = sx + child_allocation.width - req.width;
+ *y = sy;
+
+ screen = gtk_widget_get_screen (widget);
+ monitor_num = gdk_screen_get_monitor_at_window (screen,
+ gtk_widget_get_window (widget));
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
+
+ if (*x < monitor.x)
+ *x = monitor.x;
+ else if (*x + req.width > monitor.x + monitor.width)
+ *x = monitor.x + monitor.width - req.width;
+
+ if (monitor.y + monitor.height - *y - child_allocation.height >= req.height)
+ *y += child_allocation.height;
+ else if (*y - monitor.y >= req.height)
+ *y -= req.height;
+ else if (monitor.y + monitor.height - *y - child_allocation.height > *y - monitor.y)
+ *y += child_allocation.height;
+ else
+ *y -= req.height;
+
+ *push_in = FALSE;
+}
+
+static void
+entry_icon_press_callback (GtkEntry *entry,
+ GtkEntryIconPosition icon_pos,
+ GdkEventButton *event,
+ EvZoomAction *zoom_action)
+{
+ GtkWidget *menu;
+
+ if (event->button != GDK_BUTTON_PRIMARY)
+ return;
+
+ menu = get_popup (zoom_action);
+ gtk_widget_set_size_request (menu,
+ gtk_widget_get_allocated_width (GTK_WIDGET (zoom_action)),
+ -1);
+
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
+ menu_position_below, zoom_action,
+ event->button, event->time);
+}
+
+static void
+ev_zoom_action_finalize (GObject *object)
+{
+ EvZoomAction *zoom_action = EV_ZOOM_ACTION (object);
+
+ if (zoom_action->priv->model) {
+ g_object_remove_weak_pointer (G_OBJECT (zoom_action->priv->model),
+ (gpointer)&zoom_action->priv->model);
+ }
+
+ g_clear_object (&zoom_action->priv->zoom_free_section);
+
+ G_OBJECT_CLASS (ev_zoom_action_parent_class)->finalize (object);
+}
+
+static void
+ev_zoom_action_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EvZoomAction *zoom_action = EV_ZOOM_ACTION (object);
+
+ switch (prop_id) {
+ case PROP_DOCUMENT_MODEL:
+ zoom_action->priv->model = g_value_get_object (value);
+ break;
+ case PROP_MENU:
+ zoom_action->priv->menu = g_value_get_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
static void
-connect_proxy (GtkAction *action,
- GtkWidget *proxy)
+setup_initial_entry_size (EvZoomAction *zoom_action)
{
- if (EV_IS_ZOOM_ACTION_WIDGET (proxy)) {
- EvZoomAction *zoom_action = EV_ZOOM_ACTION (action);
- EvZoomActionWidget* zoom_widget = EV_ZOOM_ACTION_WIDGET (proxy);
+ GMenuModel *menu;
+ guint i;
+ gint n_items;
+ gint width = 0;
+
+ menu = g_menu_model_get_item_link (G_MENU_MODEL (zoom_action->priv->menu),
+ ZOOM_MODES_SECTION, G_MENU_LINK_SECTION);
+
+ n_items = g_menu_model_get_n_items (menu);
+ for (i = 0; i < n_items; i++) {
+ GVariant *value;
+ gint length;
- ev_zoom_action_widget_set_model (zoom_widget, zoom_action->priv->model);
- ev_zoom_action_widget_set_window (zoom_widget, zoom_action->priv->window);
- g_signal_connect (zoom_widget, "notify::popup-shown",
- G_CALLBACK (popup_shown_cb),
- action);
- g_signal_connect (ev_zoom_action_widget_get_entry (zoom_widget), "activate",
- G_CALLBACK (zoom_widget_activated_cb),
- action);
+ value = g_menu_model_get_item_attribute_value (menu, i, G_MENU_ATTRIBUTE_LABEL, NULL);
+ length = g_utf8_strlen (g_variant_get_string (value, NULL), -1);
+ if (length > width)
+ width = length;
+ g_variant_unref (value);
}
+ g_object_unref (menu);
- GTK_ACTION_CLASS (ev_zoom_action_parent_class)->connect_proxy (action, proxy);
+ /* Count the toggle size as one character more */
+ gtk_entry_set_width_chars (GTK_ENTRY (zoom_action->priv->entry), width + 1);
+}
+
+static void
+ev_zoom_action_constructed (GObject *object)
+{
+ EvZoomAction *zoom_action = EV_ZOOM_ACTION (object);
+
+ G_OBJECT_CLASS (ev_zoom_action_parent_class)->constructed (object);
+
+ zoom_action->priv->zoom_free_section =
+ g_menu_model_get_item_link (G_MENU_MODEL (zoom_action->priv->menu),
+ ZOOM_FREE_SECTION, G_MENU_LINK_SECTION);
+ ev_zoom_action_populate_free_zoom_section (zoom_action);
+
+ g_object_add_weak_pointer (G_OBJECT (zoom_action->priv->model),
+ (gpointer)&zoom_action->priv->model);
+ if (ev_document_model_get_document (zoom_action->priv->model)) {
+ ev_zoom_action_update_zoom_level (zoom_action);
+ } else {
+ ev_zoom_action_set_zoom_level (zoom_action, 1.);
+ gtk_widget_set_sensitive (GTK_WIDGET (zoom_action), FALSE);
+ }
+
+ g_signal_connect (zoom_action->priv->model, "notify::document",
+ G_CALLBACK (document_changed_cb),
+ zoom_action);
+ g_signal_connect (zoom_action->priv->model, "notify::scale",
+ G_CALLBACK (zoom_changed_cb),
+ zoom_action);
+ g_signal_connect (zoom_action->priv->model, "notify::max-scale",
+ G_CALLBACK (max_zoom_changed_cb),
+ zoom_action);
+
+ setup_initial_entry_size (zoom_action);
}
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;
+ object_class->finalize = ev_zoom_action_finalize;
+ object_class->constructed = ev_zoom_action_constructed;
+ object_class->set_property = ev_zoom_action_set_property;
+
+ g_object_class_install_property (object_class,
+ PROP_DOCUMENT_MODEL,
+ g_param_spec_object ("document-model",
+ "DocumentModel",
+ "The document model",
+ EV_TYPE_DOCUMENT_MODEL,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class,
+ PROP_MENU,
+ g_param_spec_object ("menu",
+ "Menu",
+ "The zoom popup menu",
+ G_TYPE_MENU,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
signals[ACTIVATED] =
g_signal_new ("activated",
@@ -96,50 +484,44 @@ ev_zoom_action_class_init (EvZoomActionClass *class)
}
static void
-ev_zoom_action_init (EvZoomAction *action)
+ev_zoom_action_init (EvZoomAction *zoom_action)
{
- action->priv = G_TYPE_INSTANCE_GET_PRIVATE (action, EV_TYPE_ZOOM_ACTION, EvZoomActionPrivate);
-}
+ EvZoomActionPrivate *priv;
-void
-ev_zoom_action_set_model (EvZoomAction *action,
- EvDocumentModel *model)
-{
- GSList *proxies, *l;
+ zoom_action->priv = G_TYPE_INSTANCE_GET_PRIVATE (zoom_action, EV_TYPE_ZOOM_ACTION,
EvZoomActionPrivate);
+ priv = zoom_action->priv;
- g_return_if_fail (EV_IS_ZOOM_ACTION (action));
- g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (zoom_action), GTK_ORIENTATION_VERTICAL);
- if (action->priv->model == model)
- return;
+ priv->entry = gtk_entry_new ();
+ gtk_entry_set_icon_from_icon_name (GTK_ENTRY (priv->entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ "go-down-symbolic");
+ gtk_box_pack_start (GTK_BOX (zoom_action), priv->entry, TRUE, FALSE, 0);
+ gtk_widget_show (priv->entry);
- 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);
- }
+ g_signal_connect (priv->entry, "icon-press",
+ G_CALLBACK (entry_icon_press_callback),
+ zoom_action);
+ g_signal_connect (priv->entry, "activate",
+ G_CALLBACK (entry_activated_cb),
+ zoom_action);
+ g_signal_connect_swapped (priv->entry, "focus-out-event",
+ G_CALLBACK (focus_out_cb),
+ zoom_action);
}
-void
-ev_zoom_action_set_window (EvZoomAction *action,
- EvWindow *window)
+GtkWidget *
+ev_zoom_action_new (EvDocumentModel *model,
+ GMenu *menu)
{
+ g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), NULL);
+ g_return_val_if_fail (G_IS_MENU (menu), NULL);
- GSList *proxies, *l;
-
- g_return_if_fail (EV_IS_ZOOM_ACTION (action));
- g_return_if_fail (EV_IS_WINDOW (window));
-
- if (action->priv->window == window)
- return;
-
- action->priv->window = window;
- 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_window (EV_ZOOM_ACTION_WIDGET (l->data), window);
- }
+ return GTK_WIDGET (g_object_new (EV_TYPE_ZOOM_ACTION,
+ "document-model", model,
+ "menu", menu,
+ NULL));
}
gboolean
diff --git a/shell/ev-zoom-action.h b/shell/ev-zoom-action.h
index 67a23f4..8da4ff8 100644
--- a/shell/ev-zoom-action.h
+++ b/shell/ev-zoom-action.h
@@ -25,8 +25,6 @@
#include <evince-document.h>
#include <evince-view.h>
-#include "ev-window.h"
-
G_BEGIN_DECLS
#define EV_TYPE_ZOOM_ACTION (ev_zoom_action_get_type ())
@@ -41,42 +39,20 @@ typedef struct _EvZoomActionClass EvZoomActionClass;
typedef struct _EvZoomActionPrivate EvZoomActionPrivate;
struct _EvZoomAction {
- GtkAction parent;
+ GtkBox parent;
EvZoomActionPrivate *priv;
};
struct _EvZoomActionClass {
- GtkActionClass parent_class;
-};
-
-static const struct {
- const gchar *name;
- float level;
-} zoom_levels[] = {
- { "50%", 0.5 },
- { "70%", 0.7071067811 },
- { "85%", 0.8408964152 },
- { "100%", 1.0 },
- { "125%", 1.1892071149 },
- { "150%", 1.4142135623 },
- { "175%", 1.6817928304 },
- { "200%", 2.0 },
- { "300%", 2.8284271247 },
- { "400%", 4.0 },
- { "800%", 8.0 },
- { "1600%", 16.0 },
- { "3200%", 32.0 },
- { "6400%", 64.0 }
+ GtkBoxClass parent_class;
};
-GType ev_zoom_action_get_type (void);
+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_window (EvZoomAction *action,
- EvWindow *window);
+GtkWidget *ev_zoom_action_new (EvDocumentModel *model,
+ GMenu *menu);
+gboolean ev_zoom_action_get_popup_shown (EvZoomAction *action);
G_END_DECLS
diff --git a/shell/evince-menus.ui b/shell/evince-menus.ui
index b69c341..d148e1c 100644
--- a/shell/evince-menus.ui
+++ b/shell/evince-menus.ui
@@ -174,4 +174,28 @@
</item>
</section>
</menu>
+
+ <menu id="zoom-menu">
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">Fit Pa_ge</attribute>
+ <attribute name="action">win.sizing-mode</attribute>
+ <attribute name="target">fit-page</attribute>
+ <attribute name="accel">f</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Fit _Width</attribute>
+ <attribute name="action">win.sizing-mode</attribute>
+ <attribute name="target">fit-width</attribute>
+ <attribute name="accel">w</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">_Automatic</attribute>
+ <attribute name="action">win.sizing-mode</attribute>
+ <attribute name="target">automatic</attribute>
+ </item>
+ </section>
+ <section>
+ </section>
+ </menu>
</interface>
diff --git a/shell/evince-ui.xml b/shell/evince-ui.xml
index ae51200..b4e1ba1 100644
--- a/shell/evince-ui.xml
+++ b/shell/evince-ui.xml
@@ -19,12 +19,4 @@
<separator/>
<menuitem name="SaveAttachmentAs" action="SaveAttachmentAs"/>
</popup>
-
- <popup name="ZoomSelectorPopup">
- <menuitem name="ViewFitPage" action="ViewFitPage"/>
- <menuitem name="ViewFitWidth" action="ViewFitWidth"/>
- <menuitem name="ViewZoomAutomatic" action="ViewZoomAutomatic"/>
- <separator/>
- <placeholder name="ViewZoomItems"/>
- </popup>
</ui>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]