]> www.fi.muni.cz Git - evince.git/blob - ev-page-action.c
a13d61e2d05ff834f80762c30c7256e8dec058a2
[evince.git] / 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/gtkspinbutton.h>
29 #include <gtk/gtktoolitem.h>
30 #include <gtk/gtklabel.h>
31 #include <gtk/gtkhbox.h>
32
33 struct _EvPageActionPrivate
34 {
35         int current_page;
36         int total_pages;
37 };
38
39 enum
40 {
41         PROP_0,
42         PROP_CURRENT_PAGE,
43         PROP_TOTAL_PAGES
44 };
45
46 static void ev_page_action_init       (EvPageAction *action);
47 static void ev_page_action_class_init (EvPageActionClass *class);
48
49 enum
50 {
51         GOTO_PAGE_SIGNAL,
52         LAST_SIGNAL
53 };
54
55 static guint signals[LAST_SIGNAL] = { 0 };
56
57 static GObjectClass *parent_class = NULL;
58
59 G_DEFINE_TYPE (EvPageAction, ev_page_action, GTK_TYPE_ACTION)
60
61 #define EV_PAGE_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PAGE_ACTION, EvPageActionPrivate))
62
63 static void
64 update_label (GtkAction *action, gpointer dummy, GtkWidget *proxy)
65 {
66         EvPageAction *page = EV_PAGE_ACTION (action);
67         char *text;
68         GtkWidget *label;
69
70         label = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "label"));
71
72         text = g_strdup_printf (_("of %d"), page->priv->total_pages);
73         gtk_label_set_text (GTK_LABEL (label), text);
74 }
75
76 static void
77 update_spin (GtkAction *action, gpointer dummy, GtkWidget *proxy)
78 {
79         EvPageAction *page = EV_PAGE_ACTION (action);
80         GtkWidget *spin;
81         int value;
82
83         spin = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "spin"));
84
85         value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin));
86
87         if (value != page->priv->current_page)
88         {
89                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin),
90                                            page->priv->current_page);
91         }
92 }
93
94 static void
95 value_changed_cb (GtkWidget *spin, GtkAction *action)
96 {
97         int value;
98
99         value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin));
100
101         g_signal_emit (action, signals[GOTO_PAGE_SIGNAL], 0, value);
102 }
103
104 static GtkWidget *
105 create_tool_item (GtkAction *action)
106 {
107         GtkWidget *hbox, *spin, *item, *label;
108
109         hbox = gtk_hbox_new (FALSE, 6);
110         gtk_container_set_border_width (GTK_CONTAINER (hbox), 6); 
111         gtk_widget_show (hbox);
112
113         item = GTK_WIDGET (gtk_tool_item_new ());
114         gtk_widget_show (item);
115
116         spin = gtk_spin_button_new_with_range (1, 9999, 1);
117         gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spin), 0);
118         g_object_set_data (G_OBJECT (item), "spin", spin);
119         gtk_widget_show (spin);
120
121         g_signal_connect (spin, "value_changed",
122                           G_CALLBACK (value_changed_cb),
123                           action);
124
125         label = gtk_label_new ("");
126         g_object_set_data (G_OBJECT (item), "label", label);
127         update_label (action, NULL, item);
128         gtk_widget_show (label);
129
130         gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, FALSE, 0);
131         gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
132         gtk_container_add (GTK_CONTAINER (item), hbox);
133
134         return item;
135 }
136
137 static void
138 connect_proxy (GtkAction *action, GtkWidget *proxy)
139 {
140         if (GTK_IS_TOOL_ITEM (proxy))
141         {
142                 g_signal_connect_object (action, "notify::total-pages",
143                                          G_CALLBACK (update_label),
144                                          proxy, 0);
145                 g_signal_connect_object (action, "notify::current-page",
146                                          G_CALLBACK (update_spin),
147                                          proxy, 0);
148         }
149
150         GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
151 }
152
153 static void
154 ev_page_action_init (EvPageAction *action)
155 {
156         action->priv = EV_PAGE_ACTION_GET_PRIVATE (action);
157 }
158
159 static void
160 ev_page_action_finalize (GObject *object)
161 {
162         parent_class->finalize (object);
163 }
164
165 static void
166 ev_page_action_set_property (GObject *object,
167                              guint prop_id,
168                              const GValue *value,
169                              GParamSpec *pspec)
170 {
171         EvPageAction *page = EV_PAGE_ACTION (object);
172
173         switch (prop_id)
174         {
175                 case PROP_CURRENT_PAGE:
176                         page->priv->current_page = g_value_get_int (value);
177                         break;
178                 case PROP_TOTAL_PAGES:
179                         page->priv->total_pages = g_value_get_int (value);
180                         break;
181         }
182 }
183
184 static void
185 ev_page_action_get_property (GObject *object,
186                              guint prop_id,
187                              GValue *value,
188                              GParamSpec *pspec)
189 {
190         EvPageAction *page = EV_PAGE_ACTION (object);
191
192         switch (prop_id)
193         {
194                 case PROP_CURRENT_PAGE:
195                         g_value_set_int (value, page->priv->current_page);
196                         break;
197                 case PROP_TOTAL_PAGES:
198                         g_value_set_int (value, page->priv->total_pages);
199                         break;
200         }
201 }
202
203 void
204 ev_page_action_set_current_page (EvPageAction *page, int current_page)
205 {
206         g_object_set (page, "current-page", current_page, NULL);
207 }
208
209 void
210 ev_page_action_set_total_pages (EvPageAction *page, int total_pages)
211 {
212         g_object_set (page, "total-pages", total_pages, NULL);
213 }
214
215 static void
216 ev_page_action_class_init (EvPageActionClass *class)
217 {
218         GObjectClass *object_class = G_OBJECT_CLASS (class);
219         GtkActionClass *action_class = GTK_ACTION_CLASS (class);
220
221         object_class->finalize = ev_page_action_finalize;
222         object_class->set_property = ev_page_action_set_property;
223         object_class->get_property = ev_page_action_get_property;
224
225         parent_class = g_type_class_peek_parent (class);
226
227         action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM;
228         action_class->create_tool_item = create_tool_item;
229         action_class->connect_proxy = connect_proxy;
230
231         signals[GOTO_PAGE_SIGNAL] =
232                 g_signal_new ("goto_page",
233                               G_OBJECT_CLASS_TYPE (object_class),
234                               G_SIGNAL_RUN_FIRST,
235                               G_STRUCT_OFFSET (EvPageActionClass, goto_page),
236                               NULL, NULL,
237                               g_cclosure_marshal_VOID__INT,
238                               G_TYPE_NONE,
239                               1,
240                               G_TYPE_INT);
241
242         g_object_class_install_property (object_class,
243                                          PROP_CURRENT_PAGE,
244                                          g_param_spec_int ("current-page",
245                                                            "Current Page",
246                                                            "The number of current page",
247                                                            0,
248                                                            G_MAXINT,
249                                                            0,
250                                                            G_PARAM_READWRITE));
251
252         g_object_class_install_property (object_class,
253                                          PROP_TOTAL_PAGES,
254                                          g_param_spec_int ("total-pages",
255                                                            "Total Pages",
256                                                            "The total number of pages",
257                                                            0,
258                                                            G_MAXINT,
259                                                            0,
260                                                            G_PARAM_READWRITE));
261
262         g_type_class_add_private (object_class, sizeof (EvPageActionPrivate));
263 }