2 * Copyright (C) 2003, 2004 Marco Pesenti Gritti
3 * Copyright (C) 2003, 2004 Christian Persch
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "ev-page-action.h"
25 #include "ev-window.h"
27 #include <glib/gi18n.h>
28 #include <gtk/gtkentry.h>
29 #include <gtk/gtktoolitem.h>
30 #include <gtk/gtklabel.h>
31 #include <gtk/gtkhbox.h>
34 struct _EvPageActionPrivate
47 static void ev_page_action_init (EvPageAction *action);
48 static void ev_page_action_class_init (EvPageActionClass *class);
56 static guint signals[LAST_SIGNAL] = { 0 };
58 G_DEFINE_TYPE (EvPageAction, ev_page_action, GTK_TYPE_ACTION)
60 #define EV_PAGE_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PAGE_ACTION, EvPageActionPrivate))
63 update_label (GtkAction *action, gpointer dummy, GtkWidget *proxy)
65 EvPageAction *page = EV_PAGE_ACTION (action);
69 label = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "label"));
71 text = g_strdup_printf (_("of %d"), page->priv->total_pages);
72 gtk_label_set_text (GTK_LABEL (label), text);
76 update_entry (EvPageAction *page_action, GtkWidget *entry)
80 text = g_strdup_printf ("%d", page_action->priv->current_page);
81 gtk_entry_set_text (GTK_ENTRY (entry), text);
86 sync_entry (GtkAction *action, gpointer dummy, GtkWidget *proxy)
88 EvPageAction *page_action = EV_PAGE_ACTION (action);
91 entry = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "entry"));
92 update_entry (page_action, entry);
96 activate_cb (GtkWidget *entry, GtkAction *action)
98 EvPageAction *page_action = EV_PAGE_ACTION (action);
103 text = gtk_entry_get_text (GTK_ENTRY (entry));
107 value = strtol (text, &endptr, 10);
108 if (endptr[0] == '\0') {
109 /* Page number is an integer */
110 page = MIN (G_MAXINT, value);
114 if (page > 0 && page <= page_action->priv->total_pages) {
115 g_signal_emit (action, signals[GOTO_PAGE_SIGNAL], 0, page);
117 update_entry (page_action, entry);
122 entry_size_request_cb (GtkWidget *entry,
123 GtkRequisition *requisition,
126 PangoContext *context;
127 PangoFontMetrics *metrics;
130 context = gtk_widget_get_pango_context (entry);
131 metrics = pango_context_get_metrics
132 (context, entry->style->font_desc,
133 pango_context_get_language (context));
135 digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
136 digit_width = PANGO_SCALE * ((digit_width + PANGO_SCALE - 1) / PANGO_SCALE);
138 pango_font_metrics_unref (metrics);
140 /* Space for 4 digits. Probably 3 would be enough but it doesnt
141 seem to possible to calculate entry borders without using
143 requisition->width = PANGO_PIXELS (digit_width * 4);
147 create_tool_item (GtkAction *action)
149 GtkWidget *hbox, *entry, *item, *label;
151 hbox = gtk_hbox_new (FALSE, 6);
152 gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
153 gtk_widget_show (hbox);
155 item = GTK_WIDGET (gtk_tool_item_new ());
156 gtk_widget_show (item);
158 entry = gtk_entry_new ();
159 g_signal_connect (entry, "size_request",
160 G_CALLBACK (entry_size_request_cb),
162 g_object_set_data (G_OBJECT (item), "entry", entry);
163 gtk_widget_show (entry);
165 g_signal_connect (entry, "activate",
166 G_CALLBACK (activate_cb),
169 label = gtk_label_new ("");
170 g_object_set_data (G_OBJECT (item), "label", label);
171 update_label (action, NULL, item);
172 gtk_widget_show (label);
174 gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
175 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
176 gtk_container_add (GTK_CONTAINER (item), hbox);
182 connect_proxy (GtkAction *action, GtkWidget *proxy)
184 if (GTK_IS_TOOL_ITEM (proxy))
186 g_signal_connect_object (action, "notify::total-pages",
187 G_CALLBACK (update_label),
189 g_signal_connect_object (action, "notify::current-page",
190 G_CALLBACK (sync_entry),
194 GTK_ACTION_CLASS (ev_page_action_parent_class)->connect_proxy (action, proxy);
198 ev_page_action_init (EvPageAction *action)
200 action->priv = EV_PAGE_ACTION_GET_PRIVATE (action);
204 ev_page_action_finalize (GObject *object)
206 G_OBJECT_CLASS (ev_page_action_parent_class)->finalize (object);
210 ev_page_action_set_property (GObject *object,
215 EvPageAction *page = EV_PAGE_ACTION (object);
219 case PROP_CURRENT_PAGE:
220 page->priv->current_page = g_value_get_int (value);
222 case PROP_TOTAL_PAGES:
223 page->priv->total_pages = g_value_get_int (value);
229 ev_page_action_get_property (GObject *object,
234 EvPageAction *page = EV_PAGE_ACTION (object);
238 case PROP_CURRENT_PAGE:
239 g_value_set_int (value, page->priv->current_page);
241 case PROP_TOTAL_PAGES:
242 g_value_set_int (value, page->priv->total_pages);
248 ev_page_action_set_current_page (EvPageAction *page, int current_page)
250 g_object_set (page, "current-page", current_page, NULL);
254 ev_page_action_set_total_pages (EvPageAction *page, int total_pages)
256 g_object_set (page, "total-pages", total_pages, NULL);
260 ev_page_action_class_init (EvPageActionClass *class)
262 GObjectClass *object_class = G_OBJECT_CLASS (class);
263 GtkActionClass *action_class = GTK_ACTION_CLASS (class);
265 object_class->finalize = ev_page_action_finalize;
266 object_class->set_property = ev_page_action_set_property;
267 object_class->get_property = ev_page_action_get_property;
269 action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM;
270 action_class->create_tool_item = create_tool_item;
271 action_class->connect_proxy = connect_proxy;
273 signals[GOTO_PAGE_SIGNAL] =
274 g_signal_new ("goto_page",
275 G_OBJECT_CLASS_TYPE (object_class),
277 G_STRUCT_OFFSET (EvPageActionClass, goto_page),
279 g_cclosure_marshal_VOID__INT,
284 g_object_class_install_property (object_class,
286 g_param_spec_int ("current-page",
288 "The number of current page",
294 g_object_class_install_property (object_class,
296 g_param_spec_int ("total-pages",
298 "The total number of pages",
304 g_type_class_add_private (object_class, sizeof (EvPageActionPrivate));