]> www.fi.muni.cz Git - evince.git/blob - shell/ev-page-action.c
Updated traditional Chinese translation from GNOME HK Team
[evince.git] / shell / ev-page-action.c
1 /*
2  *  Copyright (C) 2003, 2004 Marco Pesenti Gritti
3  *  Copyright (C) 2003, 2004 Christian Persch
4  *
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)
8  *  any later version.
9  *
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.
14  *
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.
18  *
19  *  $Id$
20  */
21
22 #include "config.h"
23
24 #include "ev-page-action.h"
25 #include "ev-window.h"
26
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>
32
33 struct _EvPageActionPrivate
34 {
35         EvPageCache *page_cache;
36 };
37
38
39 static void ev_page_action_init       (EvPageAction *action);
40 static void ev_page_action_class_init (EvPageActionClass *class);
41
42 G_DEFINE_TYPE (EvPageAction, ev_page_action, GTK_TYPE_ACTION)
43
44 #define EV_PAGE_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PAGE_ACTION, EvPageActionPrivate))
45
46 enum {
47         PROP_0,
48         PROP_PAGE_CACHE,
49 };
50
51 #define ENTRY_DATA      "epa-entry"
52 #define PAGE_CACHE_DATA "epa-page-cache"
53 #define SIGNAL_ID_DATA  "epa-signal-id"
54
55 static void
56 page_changed_cb (EvPageCache *page_cache,
57                  gint         page,
58                  GtkWidget   *proxy)
59 {
60         GtkWidget *entry;
61
62         entry = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), ENTRY_DATA));
63         if (page_cache != NULL) {
64                 gchar *page_label = ev_page_cache_get_page_label (page_cache, page);
65                 gtk_entry_set_text (GTK_ENTRY (entry), page_label);
66                 gtk_editable_set_position (GTK_EDITABLE (entry), -1);
67                 g_free (page_label);
68         } else {
69                 gtk_entry_set_text (GTK_ENTRY (entry), "");
70         }
71 }
72
73 static void
74 activate_cb (GtkWidget *entry, GtkAction *action)
75 {
76         EvPageAction *page = EV_PAGE_ACTION (action);
77         EvPageCache *page_cache;
78         const char *text;
79
80         text = gtk_entry_get_text (GTK_ENTRY (entry));
81         page_cache = page->priv->page_cache;
82
83         if (! ev_page_cache_set_page_label (page_cache, text)) {
84                 /* rest the entry to the current page if we were unable to
85                  * change it */
86                 gchar *page_label =
87                         ev_page_cache_get_page_label (page_cache,
88                                                       ev_page_cache_get_current_page (page_cache));
89                 gtk_entry_set_text (GTK_ENTRY (entry), page_label);
90                 gtk_editable_set_position (GTK_EDITABLE (entry), -1);
91                 g_free (page_label);
92         }
93 }
94
95 static GtkWidget *
96 create_tool_item (GtkAction *action)
97 {
98         GtkWidget *hbox, *entry, *item;
99
100         hbox = gtk_hbox_new (FALSE, 6);
101         gtk_container_set_border_width (GTK_CONTAINER (hbox), 6); 
102         gtk_widget_show (hbox);
103
104         item = GTK_WIDGET (gtk_tool_item_new ());
105         gtk_widget_show (item);
106
107         entry = gtk_entry_new ();
108         gtk_entry_set_width_chars (GTK_ENTRY (entry), 5);
109         g_object_set_data (G_OBJECT (item), ENTRY_DATA, entry);
110         gtk_widget_show (entry);
111
112         g_signal_connect (entry, "activate",
113                           G_CALLBACK (activate_cb),
114                           action);
115
116         gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
117         gtk_container_add (GTK_CONTAINER (item), hbox);
118
119         return item;
120 }
121
122 static void
123 update_page_cache (EvPageAction *page, gpointer dummy, GtkWidget *proxy)
124 {
125         EvPageCache *page_cache;
126         EvPageCache *old_page_cache;
127         guint signal_id;
128
129         page_cache = page->priv->page_cache;
130         old_page_cache = (EvPageCache *) g_object_get_data (G_OBJECT (proxy), PAGE_CACHE_DATA);
131         signal_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (proxy), SIGNAL_ID_DATA));
132
133         /* clear the old signal */
134         if (signal_id > 0 && old_page_cache)
135                 g_signal_handler_disconnect (old_page_cache, signal_id);
136         
137         if (page_cache != NULL) {
138                 signal_id = g_signal_connect (page_cache,
139                                               "page-changed",
140                                               G_CALLBACK (page_changed_cb),
141                                               proxy);
142                 /* Set the initial value */
143                 page_changed_cb (page_cache,
144                                  ev_page_cache_get_current_page (page_cache),
145                                  proxy);
146         } else {
147                 /* Or clear the entry */
148                 signal_id = 0;
149                 page_changed_cb (NULL, 0, proxy);
150         }
151         g_object_set_data (G_OBJECT (proxy), PAGE_CACHE_DATA, page_cache);
152         g_object_set_data (G_OBJECT (proxy), SIGNAL_ID_DATA, GINT_TO_POINTER (signal_id));
153 }
154
155 static void
156 connect_proxy (GtkAction *action, GtkWidget *proxy)
157 {
158         if (GTK_IS_TOOL_ITEM (proxy)) {
159                 g_signal_connect_object (action, "notify::page-cache",
160                                          G_CALLBACK (update_page_cache),
161                                          proxy, 0);
162         }
163
164         GTK_ACTION_CLASS (ev_page_action_parent_class)->connect_proxy (action, proxy);
165 }
166
167 static void
168 ev_page_action_dispose (GObject *object)
169 {
170         EvPageAction *page = EV_PAGE_ACTION (object);
171
172         if (page->priv->page_cache) {
173                 g_object_unref (page->priv->page_cache);
174                 page->priv->page_cache = NULL;
175         }
176
177         G_OBJECT_CLASS (ev_page_action_parent_class)->dispose (object);
178 }
179
180 static void
181 ev_page_action_set_property (GObject      *object,
182                              guint         prop_id,
183                              const GValue *value,
184                              GParamSpec   *pspec)
185 {
186         EvPageAction *page;
187         EvPageCache *page_cache;
188   
189         page = EV_PAGE_ACTION (object);
190
191         switch (prop_id)
192         {
193         case PROP_PAGE_CACHE:
194                 page_cache = page->priv->page_cache;
195                 page->priv->page_cache = EV_PAGE_CACHE (g_value_dup_object (value));
196                 if (page_cache)
197                         g_object_unref (page_cache);
198                 break;
199         default:
200                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
201                 break;
202         }
203 }
204
205 static void
206 ev_page_action_get_property (GObject    *object,
207                              guint       prop_id,
208                              GValue     *value,
209                              GParamSpec *pspec)
210 {
211         EvPageAction *page;
212   
213         page = EV_PAGE_ACTION (object);
214
215         switch (prop_id)
216         {
217         case PROP_PAGE_CACHE:
218                 g_value_set_object (value, page->priv->page_cache);
219                 break;
220         default:
221                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
222                 break;
223         }
224 }
225
226 void
227 ev_page_action_set_document (EvPageAction *page, EvDocument *document)
228 {
229         EvPageCache *page_cache = NULL;
230
231         if (document)
232                 page_cache = ev_document_get_page_cache (document);
233         
234         g_object_set (page, "page-cache", page_cache, NULL);
235 }
236
237 static void
238 ev_page_action_init (EvPageAction *page)
239 {
240         page->priv = EV_PAGE_ACTION_GET_PRIVATE (page);
241 }
242
243 static void
244 ev_page_action_class_init (EvPageActionClass *class)
245 {
246         GObjectClass *object_class = G_OBJECT_CLASS (class);
247         GtkActionClass *action_class = GTK_ACTION_CLASS (class);
248
249         object_class->dispose = ev_page_action_dispose;
250         object_class->set_property = ev_page_action_set_property;
251         object_class->get_property = ev_page_action_get_property;
252
253         action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM;
254         action_class->create_tool_item = create_tool_item;
255         action_class->connect_proxy = connect_proxy;
256
257         g_object_class_install_property (object_class,
258                                          PROP_PAGE_CACHE,
259                                          g_param_spec_object ("page-cache",
260                                                               "Page Cache",
261                                                               "Current page cache",
262                                                               EV_TYPE_PAGE_CACHE,
263                                                               G_PARAM_READWRITE));
264
265         g_type_class_add_private (object_class, sizeof (EvPageActionPrivate));
266 }