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.
23 #include "ev-page-action.h"
24 #include "ev-page-cache.h"
25 #include "ev-window.h"
26 #include "ev-document-links.h"
27 #include "ev-page-action-widget.h"
28 #include "ev-marshal.h"
30 #include <glib/gi18n.h>
31 #include <gtk/gtkentry.h>
32 #include <gtk/gtktoolitem.h>
33 #include <gtk/gtklabel.h>
34 #include <gtk/gtkhbox.h>
38 struct _EvPageActionPrivate
40 EvPageCache *page_cache;
45 static void ev_page_action_init (EvPageAction *action);
46 static void ev_page_action_class_init (EvPageActionClass *class);
55 static guint signals[N_SIGNALS] = {0, };
57 G_DEFINE_TYPE (EvPageAction, ev_page_action, GTK_TYPE_ACTION)
59 #define EV_PAGE_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PAGE_ACTION, EvPageActionPrivate))
68 update_pages_label (EvPageActionWidget *proxy,
70 EvPageCache *page_cache)
75 n_pages = page_cache ? ev_page_cache_get_n_pages (page_cache) : 0;
76 if (page_cache && ev_page_cache_has_nonnumeric_page_labels (page_cache)) {
77 label_text = g_strdup_printf (_("(%d of %d)"), page + 1, n_pages);
79 label_text = g_strdup_printf (_("of %d"), n_pages);
81 gtk_label_set_text (GTK_LABEL (proxy->label), label_text);
86 page_changed_cb (EvPageCache *page_cache,
88 EvPageActionWidget *proxy)
92 if (page_cache != NULL && page >= 0) {
95 gtk_entry_set_width_chars (GTK_ENTRY (proxy->entry),
96 CLAMP (ev_page_cache_get_max_label_chars (page_cache),
99 page_label = ev_page_cache_get_page_label (page_cache, page);
100 gtk_entry_set_text (GTK_ENTRY (proxy->entry), page_label);
101 gtk_editable_set_position (GTK_EDITABLE (proxy->entry), -1);
105 gtk_entry_set_text (GTK_ENTRY (proxy->entry), "");
108 update_pages_label (proxy, page, page_cache);
112 activate_cb (GtkWidget *entry, GtkAction *action)
114 EvPageAction *page = EV_PAGE_ACTION (action);
115 EvPageCache *page_cache;
121 text = gtk_entry_get_text (GTK_ENTRY (entry));
122 page_cache = page->priv->page_cache;
124 g_signal_emit (action, signals[ACTIVATE_LABEL], 0, text, &changed);
129 /* Check whether it's a valid page number */
130 page_number = atoi (text) - 1;
131 if (page_number >= 0 &&
132 page_number < ev_page_cache_get_n_pages (page_cache)) {
133 page_label = ev_page_cache_get_page_label (page_cache, page_number);
134 gtk_entry_set_text (GTK_ENTRY (entry), page_label);
135 gtk_editable_set_position (GTK_EDITABLE (entry), -1);
137 g_signal_emit (action, signals[ACTIVATE_LABEL], 0, page_label, &changed);
143 /* rest the entry to the current page if we were unable to
145 page_label = ev_page_cache_get_page_label (page_cache,
146 ev_page_cache_get_current_page (page_cache));
147 gtk_entry_set_text (GTK_ENTRY (entry), page_label);
148 gtk_editable_set_position (GTK_EDITABLE (entry), -1);
153 create_tool_item (GtkAction *action)
155 EvPageActionWidget *proxy;
158 proxy = g_object_new (ev_page_action_widget_get_type (), NULL);
159 gtk_container_set_border_width (GTK_CONTAINER (proxy), 6);
160 gtk_widget_show (GTK_WIDGET (proxy));
162 hbox = gtk_hbox_new (FALSE, 0);
163 gtk_box_set_spacing (GTK_BOX (hbox), 6);
165 proxy->entry = gtk_entry_new ();
166 gtk_entry_set_width_chars (GTK_ENTRY (proxy->entry), 5);
167 gtk_box_pack_start (GTK_BOX (hbox), proxy->entry, FALSE, FALSE, 0);
168 gtk_widget_show (proxy->entry);
169 g_signal_connect (proxy->entry, "activate",
170 G_CALLBACK (activate_cb),
173 proxy->label = gtk_label_new (NULL);
174 gtk_box_pack_start (GTK_BOX (hbox), proxy->label, FALSE, FALSE, 0);
175 gtk_widget_show (proxy->label);
177 gtk_container_add (GTK_CONTAINER (proxy), hbox);
178 gtk_widget_show (hbox);
180 return GTK_WIDGET (proxy);
184 update_page_cache (EvPageAction *page, GParamSpec *pspec, EvPageActionWidget *proxy)
186 EvPageCache *page_cache;
189 page_cache = page->priv->page_cache;
191 /* clear the old signal */
192 if (proxy->signal_id > 0 && proxy->page_cache)
193 g_signal_handler_disconnect (proxy->page_cache, proxy->signal_id);
195 if (page_cache != NULL) {
196 signal_id = g_signal_connect_object (page_cache,
198 G_CALLBACK (page_changed_cb),
200 /* Set the initial value */
201 page_changed_cb (page_cache,
202 ev_page_cache_get_current_page (page_cache),
205 /* Or clear the entry */
207 page_changed_cb (NULL, 0, proxy);
209 ev_page_action_widget_set_page_cache (proxy, page_cache);
210 proxy->signal_id = signal_id;
214 activate_link_cb (EvPageActionWidget *proxy, EvLink *link, EvPageAction *action)
216 g_signal_emit (action, signals[ACTIVATE_LINK], 0, link);
220 update_model (EvPageAction *page, GParamSpec *pspec, EvPageActionWidget *proxy)
224 g_object_get (G_OBJECT (page),
228 ev_page_action_widget_update_model (proxy, model);
232 connect_proxy (GtkAction *action, GtkWidget *proxy)
234 if (GTK_IS_TOOL_ITEM (proxy)) {
235 g_signal_connect_object (action, "notify::page-cache",
236 G_CALLBACK (update_page_cache),
238 g_signal_connect (proxy, "activate_link",
239 G_CALLBACK (activate_link_cb),
241 update_page_cache (EV_PAGE_ACTION (action), NULL,
242 EV_PAGE_ACTION_WIDGET (proxy));
243 g_signal_connect_object (action, "notify::model",
244 G_CALLBACK (update_model),
248 GTK_ACTION_CLASS (ev_page_action_parent_class)->connect_proxy (action, proxy);
252 ev_page_action_dispose (GObject *object)
254 EvPageAction *page = EV_PAGE_ACTION (object);
256 if (page->priv->page_cache) {
257 g_object_unref (page->priv->page_cache);
258 page->priv->page_cache = NULL;
261 G_OBJECT_CLASS (ev_page_action_parent_class)->dispose (object);
265 ev_page_action_set_property (GObject *object,
271 EvPageCache *page_cache;
274 page = EV_PAGE_ACTION (object);
278 case PROP_PAGE_CACHE:
279 page_cache = page->priv->page_cache;
280 page->priv->page_cache = EV_PAGE_CACHE (g_value_dup_object (value));
282 g_object_unref (page_cache);
285 model = page->priv->model;
286 page->priv->model = GTK_TREE_MODEL (g_value_dup_object (value));
288 g_object_unref (model);
291 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
297 ev_page_action_get_property (GObject *object,
304 page = EV_PAGE_ACTION (object);
308 case PROP_PAGE_CACHE:
309 g_value_set_object (value, page->priv->page_cache);
312 g_value_set_object (value, page->priv->model);
315 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
321 ev_page_action_set_document (EvPageAction *page, EvDocument *document)
323 EvPageCache *page_cache = NULL;
326 page_cache = ev_page_cache_get (document);
329 "page-cache", page_cache,
335 ev_page_action_set_model (EvPageAction *page_action,
338 g_object_set (page_action,
344 ev_page_action_grab_focus (EvPageAction *page_action)
348 proxies = gtk_action_get_proxies (GTK_ACTION (page_action));
349 for (; proxies != NULL; proxies = proxies->next) {
350 EvPageActionWidget *proxy;
352 proxy = EV_PAGE_ACTION_WIDGET (proxies->data);
353 gtk_widget_grab_focus (proxy->entry);
358 ev_page_action_init (EvPageAction *page)
360 page->priv = EV_PAGE_ACTION_GET_PRIVATE (page);
364 ev_page_action_class_init (EvPageActionClass *class)
366 GObjectClass *object_class = G_OBJECT_CLASS (class);
367 GtkActionClass *action_class = GTK_ACTION_CLASS (class);
369 object_class->dispose = ev_page_action_dispose;
370 object_class->set_property = ev_page_action_set_property;
371 object_class->get_property = ev_page_action_get_property;
373 action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM;
374 action_class->create_tool_item = create_tool_item;
375 action_class->connect_proxy = connect_proxy;
377 signals[ACTIVATE_LINK] = g_signal_new ("activate_link",
378 G_OBJECT_CLASS_TYPE (object_class),
379 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
380 G_STRUCT_OFFSET (EvPageActionClass, activate_link),
382 g_cclosure_marshal_VOID__OBJECT,
385 signals[ACTIVATE_LABEL] = g_signal_new ("activate_label",
386 G_OBJECT_CLASS_TYPE (object_class),
387 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
388 G_STRUCT_OFFSET (EvPageActionClass, activate_label),
390 ev_marshal_BOOLEAN__STRING,
394 g_object_class_install_property (object_class,
396 g_param_spec_object ("page-cache",
398 "Current page cache",
402 g_object_class_install_property (object_class,
404 g_param_spec_object ("model",
410 g_type_class_add_private (object_class, sizeof (EvPageActionPrivate));