]> www.fi.muni.cz Git - evince.git/blob - shell/ev-window.c
fd819b36742cb6790977174f2fdb9135c37b4916
[evince.git] / shell / ev-window.c
1 /* this file is part of evince, a gnome document viewer
2  *
3  *  Copyright (C) 2004 Martin Kretzschmar
4  *
5  *  Author:
6  *    Martin Kretzschmar <martink@gnome.org>
7  *
8  * Evince is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * Evince is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "ev-window.h"
28
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <glib/gi18n.h>
32 #include <gtk/gtkaboutdialog.h>
33 #include <gtk/gtkaccelgroup.h>
34 #include <gtk/gtkactiongroup.h>
35 #include <gtk/gtkmain.h>
36 #include <gtk/gtkmenuitem.h>
37 #include <gtk/gtkstatusbar.h>
38 #include <gtk/gtkstock.h>
39 #include <gtk/gtktoggleaction.h>
40 #include <gtk/gtkuimanager.h>
41 #include <gtk/gtkvbox.h>
42 #include <libgnomevfs/gnome-vfs-mime-utils.h>
43
44 #include <string.h>
45
46 #include "ev-application.h"
47
48 enum {
49         PROP_0,
50         PROP_ATTRIBUTE
51 };
52
53 enum {
54         SIGNAL,
55         N_SIGNALS
56 };
57
58 struct _EvWindowPrivate {
59         GtkWidget *main_box;
60         GtkWidget *bonobo_widget;
61         GtkUIManager *ui_manager;
62         GtkWidget *statusbar;
63         guint help_message_cid;
64 };
65
66 #if 0
67 /* enable these to add support for signals */
68 static guint ev_window_signals [N_SIGNALS] = { 0 };
69 #endif
70
71 static GObjectClass *parent_class = NULL;
72
73 G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)
74
75 #define EV_WINDOW_GET_PRIVATE(object) \
76         (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_WINDOW, EvWindowPrivate))
77
78 #if 0
79 const char *
80 ev_window_get_attribute (EvWindow *self)
81 {
82         g_return_val_if_fail (self != NULL && EV_IS_WINDOW (self), NULL);
83         
84         return self->priv->attribute;
85 }
86
87 void
88 ev_window_set_attribute (EvWindow* self, const char *attribute)
89 {
90         g_assert (self != NULL && EV_IS_WINDOW (self));
91         g_assert (attribute != NULL);
92
93         if (self->priv->attribute != NULL) {
94                 g_free (self->priv->attribute);
95         }
96
97         self->priv->attribute = g_strdup (attribute);
98
99         g_object_notify (G_OBJECT (self), "attribute");
100 }
101
102 static void
103 ev_window_get_property (GObject *object, guint prop_id, GValue *value,
104                         GParamSpec *param_spec)
105 {
106         EvWindow *self;
107
108         self = EV_WINDOW (object);
109
110         switch (prop_id) {
111         case PROP_ATTRIBUTE:
112                 g_value_set_string (value, self->priv->attribute);
113                 break;
114         default:
115                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
116                                                    prop_id,
117                                                    param_spec);
118                 break;
119         }
120 }
121
122 static void
123 ev_window_set_property (GObject *object, guint prop_id, const GValue *value,
124                         GParamSpec *param_spec)
125 {
126         EvWindow *self;
127         
128         self = EV_WINDOW (object);
129         
130         switch (prop_id) {
131         case PROP_ATTRIBUTE:
132                 ev_window_set_attribute (self, g_value_get_string (value));
133                 break;
134         default:
135                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
136                                                    prop_id,
137                                                    param_spec);
138                 break;
139         }
140 }
141 #endif
142
143 gboolean
144 ev_window_is_empty (const EvWindow *ev_window)
145 {
146         g_return_val_if_fail (EV_IS_WINDOW (ev_window), FALSE);
147         
148         return ev_window->priv->bonobo_widget == NULL;
149 }
150
151 void
152 ev_window_open (EvWindow *ev_window, const char *uri)
153 {
154 #if 0
155         char *mime_type;
156         BonoboObject *bonobo_control;
157         CORBA_Environment ev;
158         Bonobo_PersistFile pf;
159
160         mime_type = gnome_vfs_get_mime_type (uri);
161
162         g_return_if_fail (mime_type != NULL); /* FIXME set error */
163
164         if (!strcmp (mime_type, "application/pdf")) {
165                 bonobo_control = create_gpdf_control ();
166         } else if (!strcmp (mime_type, "application/postscript")) {
167                 bonobo_control = create_ggv_control ();
168         } else if (!strcmp (mime_type, "application/x-gzip")) {
169                 g_message ("Cannot open gzip-compressed file %s.", uri);
170                 goto finally;
171         } else if (!strcmp (mime_type, "application/x-bzip")) {
172                 g_message ("Cannot open bzip2-compressed file %s.", uri);
173                 goto finally;
174         } else {
175                 g_warning ("Don't know how to open %s file %s.",
176                            mime_type, uri); /* FIXME set error */
177                 goto finally;
178         }
179
180         ev_window->priv->bonobo_widget = bonobo_widget_new_control_from_objref (
181                 bonobo_object_corba_objref (bonobo_control), CORBA_OBJECT_NIL);
182         gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box),
183                             ev_window->priv->bonobo_widget,
184                             TRUE, TRUE, 0);
185         CORBA_exception_init (&ev);
186         pf = bonobo_object_query_interface (
187                 bonobo_control, "IDL:Bonobo/PersistFile:1.0", &ev);
188         Bonobo_PersistFile_load (pf, uri, &ev);
189         gtk_widget_show (ev_window->priv->bonobo_widget);
190         bonobo_object_release_unref (pf, &ev);
191         bonobo_object_unref (bonobo_control);
192         CORBA_exception_free (&ev);
193
194 finally:
195         g_free (mime_type);
196 #endif
197 }
198
199 static void
200 ev_window_cmd_file_open (GtkAction *action, EvWindow *ev_window)
201 {
202         ev_application_open (EV_APP, NULL);
203 }
204
205 static void
206 ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window)
207 {
208         g_return_if_fail (EV_IS_WINDOW (ev_window));
209
210         gtk_widget_destroy (GTK_WIDGET (ev_window));
211 }
212
213 static void
214 ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window)
215 {
216         const char *authors[] = {
217                 N_("Many..."),
218                 NULL
219         };
220
221         const char *documenters[] = {
222                 N_("Not so many..."),
223                 NULL
224         };
225
226         const char *license[] = {
227                 N_("Evince is free software; you can redistribute it and/or modify\n"
228                    "it under the terms of the GNU General Public License as published by\n"
229                    "the Free Software Foundation; either version 2 of the License, or\n"
230                    "(at your option) any later version.\n"),            
231                 N_("Evince is distributed in the hope that it will be useful,\n"
232                    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
233                    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
234                    "GNU General Public License for more details.\n"),
235                 N_("You should have received a copy of the GNU General Public License\n"
236                    "along with Evince; if not, write to the Free Software Foundation, Inc.,\n"
237                    "59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n")
238         };
239
240         char *license_trans;
241
242 #ifdef ENABLE_NLS
243         const char **p;
244
245         for (p = authors; *p; ++p)
246                 *p = _(*p);
247
248         for (p = documenters; *p; ++p)
249                 *p = _(*p);
250 #endif
251
252         license_trans = g_strconcat (_(license[0]), "\n", _(license[1]), "\n",
253                                      _(license[2]), "\n", NULL);
254
255         gtk_show_about_dialog (
256                 GTK_WINDOW (ev_window),
257                 "name", _("Evince"),
258                 "version", VERSION,
259                 "copyright",
260                 _("\xc2\xa9 1996-2004 The Evince authors"),
261                 "license", license_trans,
262                 "website", "http://www.gnome.org/projects/evince",
263                 "comments", _("PostScript and PDF File Viewer."),
264                 "authors", authors,
265                 "documenters", documenters,
266                 "translator-credits", _("translator-credits"),
267                 NULL);
268
269         g_free (license_trans);
270 }
271
272 static void
273 ev_window_view_toolbar_cb (GtkAction *action, EvWindow *ev_window)
274 {
275         g_object_set (
276                 G_OBJECT (gtk_ui_manager_get_widget (
277                                   ev_window->priv->ui_manager,
278                                   "/ToolBar")),
279                 "visible",
280                 gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)),
281                 NULL);
282 }
283
284 static void
285 ev_window_view_statusbar_cb (GtkAction *action, EvWindow *ev_window)
286 {
287         g_object_set (
288                 ev_window->priv->statusbar,
289                 "visible",
290                 gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)),
291                 NULL);
292 }
293
294 static void
295 menu_item_select_cb (GtkMenuItem *proxy, EvWindow *ev_window)
296 {
297         GtkAction *action;
298         char *message;
299
300         action = g_object_get_data (G_OBJECT (proxy), "gtk-action");
301         g_return_if_fail (action != NULL);
302         
303         g_object_get (G_OBJECT (action), "tooltip", &message, NULL);
304         if (message) {
305                 gtk_statusbar_push (GTK_STATUSBAR (ev_window->priv->statusbar),
306                                     ev_window->priv->help_message_cid, message);
307                 g_free (message);
308         }
309 }
310
311 static void
312 menu_item_deselect_cb (GtkMenuItem *proxy, EvWindow *ev_window)
313 {
314         gtk_statusbar_pop (GTK_STATUSBAR (ev_window->priv->statusbar),
315                            ev_window->priv->help_message_cid);
316 }
317
318 static void
319 connect_proxy_cb (GtkUIManager *ui_manager, GtkAction *action,
320                   GtkWidget *proxy, EvWindow *ev_window)
321 {
322         if (GTK_IS_MENU_ITEM (proxy)) {
323                 g_signal_connect (proxy, "select",
324                                   G_CALLBACK (menu_item_select_cb), ev_window);
325                 g_signal_connect (proxy, "deselect",
326                                   G_CALLBACK (menu_item_deselect_cb),
327                                   ev_window);
328         }
329 }
330
331 static void
332 disconnect_proxy_cb (GtkUIManager *ui_manager, GtkAction *action,
333                      GtkWidget *proxy, EvWindow *ev_window)
334 {
335         if (GTK_IS_MENU_ITEM (proxy)) {
336                 g_signal_handlers_disconnect_by_func
337                         (proxy, G_CALLBACK (menu_item_select_cb), ev_window);
338                 g_signal_handlers_disconnect_by_func
339                         (proxy, G_CALLBACK (menu_item_deselect_cb), ev_window);
340         }
341 }
342
343 static void
344 ev_window_dispose (GObject *object)
345 {
346         EvWindowPrivate *priv;
347
348         g_return_if_fail (object != NULL && EV_IS_WINDOW (object));
349
350         priv = EV_WINDOW (object)->priv;
351
352         g_object_unref (priv->ui_manager);
353
354         G_OBJECT_CLASS (parent_class)->dispose (object);
355 }
356
357 static void
358 ev_window_class_init (EvWindowClass *ev_window_class)
359 {
360         GObjectClass *g_object_class;
361
362         parent_class = g_type_class_peek_parent (ev_window_class);
363
364         g_object_class = G_OBJECT_CLASS (ev_window_class);
365         g_object_class->dispose = ev_window_dispose;
366
367         g_type_class_add_private (g_object_class, sizeof (EvWindowPrivate));
368
369 #if 0
370         /* setting up signal system */
371         ev_window_class->signal = ev_window_signal;
372
373         ev_window_signals [SIGNAL] = g_signal_new (
374                 "signal",
375                 EV_TYPE_WINDOW,
376                 G_SIGNAL_RUN_LAST,
377                 G_STRUCT_OFFSET (EvWindowClass,
378                                  signal),
379                 NULL,
380                 NULL,
381                 g_cclosure_marshal_VOID__STRING,
382                 G_TYPE_NONE,
383                 0);
384         /* setting up property system */
385         g_object_class->set_property = ev_window_set_property;
386         g_object_class->get_property = ev_window_get_property;
387
388         g_object_class_install_property (
389                 g_object_class,
390                 PROP_ATTRIBUTE,
391                 g_param_spec_string ("attribute",
392                                      "Attribute",
393                                      "A simple unneccessary attribute that "
394                                      "does nothing special except being a "
395                                      "demonstration for the correct implem"
396                                      "entation of a GObject property",
397                                      "default_value",
398                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
399 #endif
400 }
401
402 /* Normal items */
403 static GtkActionEntry entries[] = {
404         { "File", NULL, N_("_File") },
405         { "View", NULL, N_("_View") },
406         { "Help", NULL, N_("_Help") },
407
408         /* File menu */
409         { "FileOpen", GTK_STOCK_OPEN, N_("_Open"), "<control>O",
410           N_("Open a file"),
411           G_CALLBACK (ev_window_cmd_file_open) },
412         { "FileCloseWindow", GTK_STOCK_CLOSE, N_("_Close"), "<control>W",
413           N_("Close this window"),
414           G_CALLBACK (ev_window_cmd_file_close_window) },
415
416         /* Help menu */
417         { "HelpAbout", NULL, N_("_About"), NULL,
418           N_("Display credits for the document viewer creators"),
419           G_CALLBACK (ev_window_cmd_help_about) },
420 };
421
422 /* Toggle items */
423 static GtkToggleActionEntry toggle_entries[] = {
424         /* View Menu */
425         { "ViewToolbar", NULL, N_("_Toolbar"), "<shift><control>T",
426           N_("Show or hide toolbar"),
427           G_CALLBACK (ev_window_view_toolbar_cb), TRUE },
428         { "ViewStatusbar", NULL, N_("_Statusbar"), NULL,
429           N_("Show or hide statusbar"),
430           G_CALLBACK (ev_window_view_statusbar_cb), TRUE },
431 };
432
433 static void
434 ev_window_init (EvWindow *ev_window)
435 {
436         GtkActionGroup *action_group;
437         GtkAccelGroup *accel_group;
438         GError *error = NULL;
439         GtkWidget *menubar;
440         GtkWidget *toolbar;
441
442         ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window);
443
444         gtk_window_set_title (GTK_WINDOW (ev_window), _("Evince"));
445
446         ev_window->priv->main_box = gtk_vbox_new (FALSE, 0);
447         gtk_container_add (GTK_CONTAINER (ev_window), ev_window->priv->main_box);
448         gtk_widget_show (ev_window->priv->main_box);
449
450         action_group = gtk_action_group_new ("MenuActions");
451         gtk_action_group_set_translation_domain (action_group, NULL);
452         gtk_action_group_add_actions (action_group, entries,
453                                       G_N_ELEMENTS (entries), ev_window);
454         gtk_action_group_add_toggle_actions (action_group, toggle_entries,
455                                              G_N_ELEMENTS (toggle_entries),
456                                              ev_window);
457
458         ev_window->priv->ui_manager = gtk_ui_manager_new ();
459         gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
460                                             action_group, 0);
461
462         accel_group =
463                 gtk_ui_manager_get_accel_group (ev_window->priv->ui_manager);
464         gtk_window_add_accel_group (GTK_WINDOW (ev_window), accel_group);
465
466         g_signal_connect (ev_window->priv->ui_manager, "connect_proxy",
467                           G_CALLBACK (connect_proxy_cb), ev_window);
468         g_signal_connect (ev_window->priv->ui_manager, "disconnect_proxy",
469                           G_CALLBACK (disconnect_proxy_cb), ev_window);
470
471         if (!gtk_ui_manager_add_ui_from_file (ev_window->priv->ui_manager,
472                                               DATADIR"/evince-ui.xml",
473                                               &error)) {
474                 g_message ("building menus failed: %s", error->message);
475                 g_error_free (error);
476         }
477
478         menubar = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
479                                              "/MainMenu");
480         gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box), menubar,
481                             FALSE, FALSE, 0);
482
483         toolbar = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
484                                              "/ToolBar");
485         gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box), toolbar,
486                             FALSE, FALSE, 0);
487
488         ev_window->priv->statusbar = gtk_statusbar_new ();
489         gtk_widget_show (ev_window->priv->statusbar);
490         gtk_box_pack_end (GTK_BOX (ev_window->priv->main_box),
491                           ev_window->priv->statusbar,
492                           FALSE, TRUE, 0);
493         ev_window->priv->help_message_cid = gtk_statusbar_get_context_id
494                 (GTK_STATUSBAR (ev_window->priv->statusbar), "help_message");
495
496 }