]> www.fi.muni.cz Git - evince.git/blob - shell/ev-window.c
When building with D-Bus support, listen for multimedia key events from
[evince.git] / shell / ev-window.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
2 /* this file is part of evince, a gnome document viewer
3  *
4  *  Copyright (C) 2004 Martin Kretzschmar
5  *  Copyright (C) 2004 Red Hat, Inc.
6  *  Copyright (C) 2000, 2001, 2002, 2003, 2004 Marco Pesenti Gritti
7  *  Copyright (C) 2003, 2004, 2005 Christian Persch
8  *
9  *  Author:
10  *    Martin Kretzschmar <martink@gnome.org>
11  *
12  * Evince is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * Evince is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "ev-window.h"
32 #include "ev-window-title.h"
33 #include "ev-navigation-action.h"
34 #include "ev-page-action.h"
35 #include "ev-open-recent-action.h"
36 #include "ev-sidebar.h"
37 #include "ev-sidebar-links.h"
38 #include "ev-sidebar-attachments.h"
39 #include "ev-sidebar-thumbnails.h"
40 #include "ev-view.h"
41 #include "ev-password.h"
42 #include "ev-password-view.h"
43 #include "ev-properties-dialog.h"
44 #include "ev-file-exporter.h"
45 #include "ev-document-thumbnails.h"
46 #include "ev-document-links.h"
47 #include "ev-document-fonts.h"
48 #include "ev-document-find.h"
49 #include "ev-document-images.h"
50 #include "ev-document-security.h"
51 #include "ev-document-factory.h"
52 #include "ev-job-queue.h"
53 #include "ev-jobs.h"
54 #include "ev-sidebar-page.h"
55 #include "eggfindbar.h"
56 #include "egg-toolbar-editor.h"
57 #include "egg-editable-toolbar.h"
58 #include "egg-toolbars-model.h"
59 #include "ephy-zoom.h"
60 #include "ephy-zoom-action.h"
61 #include "ev-application.h"
62 #include "ev-stock-icons.h"
63 #include "ev-metadata-manager.h"
64 #include "ev-file-helpers.h"
65 #include "ev-utils.h"
66 #include "ev-history.h"
67 #include "ev-image.h"
68 #include "ev-message-area.h"
69 #include "ev-mount-operation.h"
70 #include "ev-file-monitor.h"
71 #ifdef ENABLE_DBUS
72 #include "ev-media-player-keys.h"
73 #endif /* ENABLE_DBUS */
74
75 #include <gtk/gtkprintunixdialog.h>
76
77 #ifdef ENABLE_PDF
78 #include <poppler.h>
79 #endif
80
81 #include <glib/gstdio.h>
82 #include <glib/gi18n.h>
83 #include <gtk/gtk.h>
84 #include <gio/gio.h>
85 #include <gconf/gconf-client.h>
86
87 #include <errno.h>
88 #include <stdlib.h>
89 #include <string.h>
90 #include <unistd.h>
91
92 typedef enum {
93         PAGE_MODE_DOCUMENT,
94         PAGE_MODE_PASSWORD
95 } EvWindowPageMode;
96
97 typedef enum {
98         EV_CHROME_MENUBAR       = 1 << 0,
99         EV_CHROME_TOOLBAR       = 1 << 1,
100         EV_CHROME_FINDBAR       = 1 << 2,
101         EV_CHROME_RAISE_TOOLBAR = 1 << 3,
102         EV_CHROME_FULLSCREEN_TOOLBAR    = 1 << 4,
103         EV_CHROME_SIDEBAR       = 1 << 5,
104         EV_CHROME_PREVIEW_TOOLBAR       = 1 << 6,
105         EV_CHROME_NORMAL        = EV_CHROME_MENUBAR | EV_CHROME_TOOLBAR | EV_CHROME_SIDEBAR
106 } EvChrome;
107
108 struct _EvWindowPrivate {
109         /* UI */
110         EvChrome chrome;
111
112         GtkWidget *main_box;
113         GtkWidget *menubar;
114         GtkWidget *toolbar;
115         GtkWidget *hpaned;
116         GtkWidget *view_box;
117         GtkWidget *sidebar;
118         GtkWidget *find_bar;
119         GtkWidget *scrolled_window;
120         GtkWidget *view;
121         GtkWidget *message_area;
122         GtkWidget *password_view;
123         GtkWidget *sidebar_thumbs;
124         GtkWidget *sidebar_links;
125         GtkWidget *sidebar_attachments;
126
127         /* Dialogs */
128         GtkWidget *properties;
129         GtkWidget *print_dialog;
130         GtkWidget *password_dialog;
131
132         /* UI Builders */
133         GtkActionGroup   *action_group;
134         GtkActionGroup   *view_popup_action_group;
135         GtkActionGroup   *attachment_popup_action_group;
136         GtkRecentManager *recent_manager;
137         GtkActionGroup   *recent_action_group;
138         guint             recent_ui_id;
139         GtkUIManager     *ui_manager;
140
141         /* Fullscreen mode */
142         GtkWidget *fullscreen_toolbar;
143
144         /* Presentation mode */
145         guint      presentation_timeout_id;
146
147         /* Preview mode */
148         GtkWidget *preview_toolbar;
149         gchar     *print_settings_file;
150
151         /* Popup view */
152         GtkWidget *view_popup;
153         EvLink    *link;
154         EvImage   *image;
155
156         /* Popup attachment */
157         GtkWidget    *attachment_popup;
158         GList        *attach_list;
159
160         /* Document */
161         char *uri;
162         char *local_uri;
163         EvLinkDest *dest;
164         gboolean unlink_temp_file;
165         gboolean in_reload;
166         EvFileMonitor *monitor;
167         
168         EvDocument *document;
169         EvHistory *history;
170         EvPageCache *page_cache;
171         EvWindowPageMode page_mode;
172         EvWindowTitle *title;
173
174         EvJob            *load_job;
175         EvJob            *reload_job;
176         EvJob            *thumbnail_job;
177         EvJob            *save_job;
178         EvJob            *print_job;
179
180         /* Printing */
181         gboolean          print_preview;
182         GtkPrintJob      *gtk_print_job;
183         GtkPrinter       *printer;
184         GtkPrintSettings *print_settings;
185         GtkPageSetup     *print_page_setup;
186
187 };
188
189 #define EV_WINDOW_GET_PRIVATE(object) \
190         (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_WINDOW, EvWindowPrivate))
191
192 #define PAGE_SELECTOR_ACTION    "PageSelector"
193 #define ZOOM_CONTROL_ACTION     "ViewZoom"
194 #define NAVIGATION_ACTION       "Navigation"
195
196 #define GCONF_OVERRIDE_RESTRICTIONS "/apps/evince/override_restrictions"
197 #define GCONF_LOCKDOWN_SAVE         "/desktop/gnome/lockdown/disable_save_to_disk"
198 #define GCONF_LOCKDOWN_PRINT        "/desktop/gnome/lockdown/disable_printing"
199
200 #define PRESENTATION_TIMEOUT 5
201
202 #define SIDEBAR_DEFAULT_SIZE    132
203 #define LINKS_SIDEBAR_ID "links"
204 #define THUMBNAILS_SIDEBAR_ID "thumbnails"
205 #define ATTACHMENTS_SIDEBAR_ID "attachments"
206
207 static const gchar *document_print_settings[] = {
208         GTK_PRINT_SETTINGS_N_COPIES,
209         GTK_PRINT_SETTINGS_COLLATE,
210         GTK_PRINT_SETTINGS_REVERSE,
211         GTK_PRINT_SETTINGS_NUMBER_UP,
212         GTK_PRINT_SETTINGS_SCALE,
213         GTK_PRINT_SETTINGS_PRINT_PAGES,
214         GTK_PRINT_SETTINGS_PAGE_RANGES,
215         GTK_PRINT_SETTINGS_PAGE_SET
216 };
217
218 static void     ev_window_update_actions                (EvWindow         *ev_window);
219 static void     ev_window_sidebar_visibility_changed_cb (EvSidebar        *ev_sidebar,
220                                                          GParamSpec       *pspec,
221                                                          EvWindow         *ev_window);
222 static void     ev_window_set_page_mode                 (EvWindow         *window,
223                                                          EvWindowPageMode  page_mode);
224 static void     ev_window_load_job_cb                   (EvJobLoad        *job,
225                                                          gpointer          data);
226 static void     ev_window_reload_document               (EvWindow         *window);
227 static void     ev_window_reload_job_cb                 (EvJobLoad        *job,
228                                                          EvWindow         *window);
229 static void     ev_window_set_icon_from_thumbnail       (EvJobThumbnail   *job,
230                                                          EvWindow         *ev_window);
231 static void     ev_window_print_job_cb                  (EvJobPrint       *job,
232                                                          EvWindow         *window);
233 static void     ev_window_save_job_cb                   (EvJobSave        *save,
234                                                          EvWindow         *window);
235 static void     ev_window_sizing_mode_changed_cb        (EvView           *view,
236                                                          GParamSpec       *pspec,
237                                                          EvWindow         *ev_window);
238 static void     ev_window_zoom_changed_cb               (EvView           *view,
239                                                          GParamSpec       *pspec,
240                                                          EvWindow         *ev_window);
241 static void     ev_window_add_recent                    (EvWindow         *window,
242                                                          const char       *filename);
243 static void     ev_window_run_fullscreen                (EvWindow         *window);
244 static void     ev_window_stop_fullscreen               (EvWindow         *window,
245                                                          gboolean          unfullscreen_window);
246 static void     ev_window_cmd_view_fullscreen           (GtkAction        *action,
247                                                          EvWindow         *window);
248 static void     ev_window_run_presentation              (EvWindow         *window);
249 static void     ev_window_stop_presentation             (EvWindow         *window,
250                                                          gboolean          unfullscreen_window);
251 static void     ev_window_cmd_view_presentation         (GtkAction        *action,
252                                                          EvWindow         *window);
253 static void     ev_window_run_preview                   (EvWindow         *window);
254 static void     ev_view_popup_cmd_open_link             (GtkAction        *action,
255                                                          EvWindow         *window);
256 static void     ev_view_popup_cmd_open_link_new_window  (GtkAction        *action,
257                                                          EvWindow         *window);
258 static void     ev_view_popup_cmd_copy_link_address     (GtkAction        *action,
259                                                          EvWindow         *window);
260 static void     ev_view_popup_cmd_save_image_as         (GtkAction        *action,
261                                                          EvWindow         *window);
262 static void     ev_view_popup_cmd_copy_image            (GtkAction        *action,
263                                                          EvWindow         *window);
264 static void     ev_attachment_popup_cmd_open_attachment (GtkAction        *action,
265                                                          EvWindow         *window);
266 static void     ev_attachment_popup_cmd_save_attachment_as (GtkAction     *action, 
267                                                          EvWindow         *window);
268 static void     ev_window_cmd_view_best_fit             (GtkAction        *action, 
269                                                          EvWindow         *ev_window);
270 static void     ev_window_cmd_view_page_width           (GtkAction        *action, 
271                                                          EvWindow         *ev_window);
272 static void     view_handle_link_cb                     (EvView           *view, 
273                                                          EvLink           *link, 
274                                                          EvWindow         *window);
275 static void     ev_window_cmd_edit_find                 (GtkAction        *action,
276                                                          EvWindow         *ev_window);
277 static void     find_bar_search_changed_cb              (EggFindBar       *find_bar,
278                                                          GParamSpec       *param,
279                                                          EvWindow         *ev_window);
280 static void     ev_window_do_preview_print              (EvWindow         *window);
281 static void     ev_window_load_file_remote              (EvWindow         *ev_window,
282                                                          GFile            *source_file);
283
284 G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)
285
286 static void
287 ev_window_set_action_sensitive (EvWindow   *ev_window,
288                                 const char *name,
289                                 gboolean    sensitive)
290 {
291         GtkAction *action = gtk_action_group_get_action (ev_window->priv->action_group,
292                                                          name);
293         gtk_action_set_sensitive (action, sensitive);
294 }
295
296
297 static void
298 ev_window_setup_action_sensitivity (EvWindow *ev_window)
299 {
300         EvDocument *document = ev_window->priv->document;
301         const EvDocumentInfo *info = NULL;
302
303         gboolean has_document = FALSE;
304         gboolean ok_to_print = TRUE;
305         gboolean ok_to_copy = TRUE;
306         gboolean has_properties = TRUE;
307         gboolean override_restrictions = TRUE;
308         gboolean can_get_text = FALSE;
309         gboolean has_pages = FALSE;
310         gboolean can_find = FALSE;
311
312         GConfClient *client;
313
314         if (document) {
315                 has_document = TRUE;
316                 info = ev_page_cache_get_info (ev_window->priv->page_cache);
317         }
318
319         if (has_document && ev_window->priv->page_cache) {
320                 has_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache) > 0;
321         }
322
323         if (!info || info->fields_mask == 0) {
324                 has_properties = FALSE;
325         }
326
327         if (has_document && EV_IS_SELECTION (document)) {
328                 can_get_text = TRUE;
329         }
330         
331         if (has_pages && EV_IS_DOCUMENT_FIND (document)) {
332                 can_find = TRUE;
333         }
334
335         client = gconf_client_get_default ();
336         override_restrictions = gconf_client_get_bool (client, 
337                                                        GCONF_OVERRIDE_RESTRICTIONS, 
338                                                        NULL);
339         if (!override_restrictions && info && info->fields_mask & EV_DOCUMENT_INFO_PERMISSIONS) {
340                 ok_to_print = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_PRINT);
341                 ok_to_copy = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_COPY);
342         }
343
344         if (has_document && !EV_IS_FILE_EXPORTER(document))
345                 ok_to_print = FALSE;
346
347         
348         if (gconf_client_get_bool (client, GCONF_LOCKDOWN_SAVE, NULL)) {
349                 ok_to_copy = FALSE;
350         }
351
352         if (gconf_client_get_bool (client, GCONF_LOCKDOWN_PRINT, NULL)) {
353                 ok_to_print = FALSE;
354         }
355
356         g_object_unref (client);
357
358         /* File menu */
359         ev_window_set_action_sensitive (ev_window, "FileOpenCopy", has_document);
360         ev_window_set_action_sensitive (ev_window, "FileSaveAs", has_document && ok_to_copy);
361         ev_window_set_action_sensitive (ev_window, "FilePrintSetup", has_pages && ok_to_print);
362         ev_window_set_action_sensitive (ev_window, "FilePrint", has_pages && ok_to_print);
363         ev_window_set_action_sensitive (ev_window, "FileProperties", has_document && has_properties);
364
365         /* Edit menu */
366         ev_window_set_action_sensitive (ev_window, "EditSelectAll", has_pages && can_get_text);
367         ev_window_set_action_sensitive (ev_window, "EditFind", can_find);
368         ev_window_set_action_sensitive (ev_window, "Slash", can_find);
369         ev_window_set_action_sensitive (ev_window, "EditRotateLeft", has_pages);
370         ev_window_set_action_sensitive (ev_window, "EditRotateRight", has_pages);
371
372         /* View menu */
373         ev_window_set_action_sensitive (ev_window, "ViewContinuous", has_pages);
374         ev_window_set_action_sensitive (ev_window, "ViewDual", has_pages);
375         ev_window_set_action_sensitive (ev_window, "ViewBestFit", has_pages);
376         ev_window_set_action_sensitive (ev_window, "ViewPageWidth", has_pages);
377         ev_window_set_action_sensitive (ev_window, "ViewReload", has_pages);
378         ev_window_set_action_sensitive (ev_window, "ViewAutoscroll", has_pages);
379
380         /* Toolbar-specific actions: */
381         ev_window_set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages);
382         ev_window_set_action_sensitive (ev_window, ZOOM_CONTROL_ACTION,  has_pages);
383         ev_window_set_action_sensitive (ev_window, NAVIGATION_ACTION,  FALSE);
384         ev_window_set_action_sensitive (ev_window, "PreviewPrint", has_pages && ok_to_print);
385
386         ev_window_update_actions (ev_window);
387 }
388
389 static void
390 ev_window_update_actions (EvWindow *ev_window)
391 {
392         EvView *view = EV_VIEW (ev_window->priv->view);
393         int n_pages = 0, page = -1;
394         gboolean has_pages = FALSE;
395         gboolean presentation_mode;
396
397         if (ev_window->priv->document && ev_window->priv->page_cache) {
398                 page = ev_page_cache_get_current_page (ev_window->priv->page_cache);
399                 n_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache);
400                 has_pages = n_pages > 0;
401         }
402
403         ev_window_set_action_sensitive (ev_window, "EditCopy",
404                                         has_pages &&
405                                         ev_view_get_has_selection (view));
406         ev_window_set_action_sensitive (ev_window, "EditFindNext",
407                                         ev_view_can_find_next (view));
408         ev_window_set_action_sensitive (ev_window, "EditFindPrevious",
409                                         ev_view_can_find_previous (view));
410
411         presentation_mode = ev_view_get_presentation (view);
412         
413         ev_window_set_action_sensitive (ev_window, "ViewZoomIn",
414                                         has_pages &&
415                                         ev_view_can_zoom_in (view) &&
416                                         !presentation_mode);
417         ev_window_set_action_sensitive (ev_window, "ViewZoomOut",
418                                         has_pages &&
419                                         ev_view_can_zoom_out (view) &&
420                                         !presentation_mode);
421         
422         /* Go menu */
423         if (has_pages) {
424                 ev_window_set_action_sensitive (ev_window, "GoPreviousPage", page > 0);
425                 ev_window_set_action_sensitive (ev_window, "GoNextPage", page < n_pages - 1);
426                 ev_window_set_action_sensitive (ev_window, "GoFirstPage", page > 0);
427                 ev_window_set_action_sensitive (ev_window, "GoLastPage", page < n_pages - 1);
428         } else {
429                 ev_window_set_action_sensitive (ev_window, "GoFirstPage", FALSE);
430                 ev_window_set_action_sensitive (ev_window, "GoPreviousPage", FALSE);
431                 ev_window_set_action_sensitive (ev_window, "GoNextPage", FALSE);
432                 ev_window_set_action_sensitive (ev_window, "GoLastPage", FALSE);
433         }
434
435         if (has_pages &&
436             ev_view_get_sizing_mode (view) != EV_SIZING_FIT_WIDTH &&
437             ev_view_get_sizing_mode (view) != EV_SIZING_BEST_FIT) {
438                 GtkAction *action;
439                 float      zoom;
440                 float      real_zoom;
441
442                 action = gtk_action_group_get_action (ev_window->priv->action_group, 
443                                                       ZOOM_CONTROL_ACTION);
444
445                 real_zoom = ev_view_get_zoom (EV_VIEW (ev_window->priv->view));
446                 real_zoom *= 72.0 / get_screen_dpi (GTK_WINDOW (ev_window));
447                 zoom = ephy_zoom_get_nearest_zoom_level (real_zoom);
448
449                 ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action), zoom);
450         }
451 }
452
453 static void
454 ev_window_set_view_accels_sensitivity (EvWindow *window, gboolean sensitive)
455 {
456         gboolean can_find;
457
458         can_find = window->priv->document && 
459             EV_IS_DOCUMENT_FIND (window->priv->document);
460
461         if (window->priv->action_group) {
462                 ev_window_set_action_sensitive (window, "PageDown", sensitive);
463                 ev_window_set_action_sensitive (window, "PageUp", sensitive);
464                 ev_window_set_action_sensitive (window, "Space", sensitive);
465                 ev_window_set_action_sensitive (window, "ShiftSpace", sensitive);
466                 ev_window_set_action_sensitive (window, "BackSpace", sensitive);
467                 ev_window_set_action_sensitive (window, "ShiftBackSpace", sensitive);
468                 ev_window_set_action_sensitive (window, "Return", sensitive);
469                 ev_window_set_action_sensitive (window, "ShiftReturn", sensitive);
470                 ev_window_set_action_sensitive (window, "Plus", sensitive);
471                 ev_window_set_action_sensitive (window, "Minus", sensitive);
472                 ev_window_set_action_sensitive (window, "KpPlus", sensitive);
473                 ev_window_set_action_sensitive (window, "KpMinus", sensitive);
474                 ev_window_set_action_sensitive (window, "Equal", sensitive);
475
476                 ev_window_set_action_sensitive (window, "Slash", sensitive && can_find);
477         }
478 }
479
480 static void
481 set_widget_visibility (GtkWidget *widget, gboolean visible)
482 {
483         g_assert (GTK_IS_WIDGET (widget));
484         
485         if (visible)
486                 gtk_widget_show (widget);
487         else
488                 gtk_widget_hide (widget);
489 }
490
491 static void
492 update_chrome_visibility (EvWindow *window)
493 {
494         EvWindowPrivate *priv = window->priv;
495         gboolean menubar, toolbar, findbar, fullscreen_toolbar, sidebar;
496         gboolean fullscreen_mode, presentation, fullscreen;
497         gboolean preview_toolbar;
498
499         presentation = ev_view_get_presentation (EV_VIEW (priv->view));
500         fullscreen = ev_view_get_fullscreen (EV_VIEW (priv->view));
501         fullscreen_mode = fullscreen || presentation;
502
503         menubar = (priv->chrome & EV_CHROME_MENUBAR) != 0 && !fullscreen_mode;
504         toolbar = ((priv->chrome & EV_CHROME_TOOLBAR) != 0  || 
505                    (priv->chrome & EV_CHROME_RAISE_TOOLBAR) != 0) && !fullscreen_mode;
506         fullscreen_toolbar = ((priv->chrome & EV_CHROME_FULLSCREEN_TOOLBAR) != 0 || 
507                               (priv->chrome & EV_CHROME_RAISE_TOOLBAR) != 0) && fullscreen;
508         findbar = (priv->chrome & EV_CHROME_FINDBAR) != 0;
509         sidebar = (priv->chrome & EV_CHROME_SIDEBAR) != 0 && !presentation;
510         preview_toolbar = (priv->chrome& EV_CHROME_PREVIEW_TOOLBAR);
511
512         set_widget_visibility (priv->menubar, menubar); 
513         set_widget_visibility (priv->toolbar, toolbar);
514         set_widget_visibility (priv->find_bar, findbar);
515         set_widget_visibility (priv->sidebar, sidebar);
516         
517         if (priv->preview_toolbar)
518                 set_widget_visibility (priv->preview_toolbar, preview_toolbar);
519
520         ev_window_set_action_sensitive (window, "EditToolbar", toolbar);
521         gtk_widget_set_sensitive (priv->menubar, menubar);
522
523         if (priv->fullscreen_toolbar != NULL) {
524                 set_widget_visibility (priv->fullscreen_toolbar, fullscreen_toolbar);
525         }
526 }
527
528 static void
529 update_chrome_flag (EvWindow *window, EvChrome flag, gboolean active)
530 {
531         EvWindowPrivate *priv = window->priv;
532         
533         if (active) {
534                 priv->chrome |= flag;
535         } else {
536                 priv->chrome &= ~flag;
537         }
538 }
539
540 static void
541 update_sizing_buttons (EvWindow *window)
542 {
543         GtkActionGroup *action_group = window->priv->action_group;
544         GtkAction *action;
545         gboolean best_fit, page_width;
546         EvSizingMode sizing_mode;
547
548         if (window->priv->view == NULL)
549                 return;
550
551         g_object_get (window->priv->view,
552                       "sizing_mode", &sizing_mode,
553                       NULL);
554
555         switch (sizing_mode) {
556                 case EV_SIZING_BEST_FIT:
557                         best_fit = TRUE;
558                         page_width = FALSE;
559                         break;
560                 case EV_SIZING_FIT_WIDTH:
561                         best_fit = FALSE;
562                         page_width = TRUE;
563                         break;
564                 default:
565                         best_fit = page_width = FALSE;
566                         break;
567         }
568
569         action = gtk_action_group_get_action (action_group, "ViewBestFit");
570         g_signal_handlers_block_by_func
571                 (action, G_CALLBACK (ev_window_cmd_view_best_fit), window);
572         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), best_fit);
573         g_signal_handlers_unblock_by_func
574                 (action, G_CALLBACK (ev_window_cmd_view_best_fit), window);
575
576         action = gtk_action_group_get_action (action_group, "ViewPageWidth");   
577         g_signal_handlers_block_by_func
578                 (action, G_CALLBACK (ev_window_cmd_view_page_width), window);
579         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), page_width);
580         g_signal_handlers_unblock_by_func
581                 (action, G_CALLBACK (ev_window_cmd_view_page_width), window);
582
583         action = gtk_action_group_get_action (window->priv->action_group, 
584                                               ZOOM_CONTROL_ACTION);     
585         if (best_fit) {
586                 ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action), 
587                                                  EPHY_ZOOM_BEST_FIT);
588         } else if (page_width) {
589                 ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action), 
590                                                  EPHY_ZOOM_FIT_WIDTH);
591         }
592 }
593
594 /**
595  * ev_window_is_empty:
596  * @ev_window: The instance of the #EvWindow.
597  *
598  * It does look if there is any document loaded or if there is any job to load
599  * a document.
600  *
601  * Returns: %TRUE if there isn't any document loaded or any any documente to be
602  *          loaded, %FALSE in other case.
603  */
604 gboolean
605 ev_window_is_empty (const EvWindow *ev_window)
606 {
607         g_return_val_if_fail (EV_IS_WINDOW (ev_window), FALSE);
608
609         return (ev_window->priv->document == NULL) && 
610                 (ev_window->priv->load_job == NULL);
611 }
612
613 static void
614 ev_window_set_message_area (EvWindow  *window,
615                             GtkWidget *area)
616 {
617         if (window->priv->message_area == area)
618                 return;
619
620         if (window->priv->message_area)
621                 gtk_widget_destroy (window->priv->message_area);
622         window->priv->message_area = area;
623
624         if (!area)
625                 return;
626
627         gtk_box_pack_start (GTK_BOX (window->priv->view_box),
628                             window->priv->message_area,
629                             FALSE, FALSE, 0);
630         gtk_box_reorder_child (GTK_BOX (window->priv->view_box),
631                                window->priv->message_area, 0);
632         g_object_add_weak_pointer (G_OBJECT (window->priv->message_area),
633                                    (gpointer) &(window->priv->message_area));
634 }
635
636 static void
637 ev_window_message_area_response_cb (EvMessageArea *area,
638                                     gint           response_id,
639                                     EvWindow      *window)
640 {
641         ev_window_set_message_area (window, NULL);
642 }
643
644 static void
645 ev_window_error_message (GtkWindow *window, const gchar *msg, GError *error)
646 {
647         GtkWidget *area;
648
649         if (EV_WINDOW (window)->priv->message_area)
650                 return;
651
652         area = ev_message_area_new (GTK_MESSAGE_ERROR,
653                                     msg,
654                                     GTK_STOCK_CLOSE,
655                                     GTK_RESPONSE_CANCEL,
656                                     NULL);
657         if (error)
658                 ev_message_area_set_secondary_text (EV_MESSAGE_AREA (area), error->message);
659         g_signal_connect (area, "response",
660                           G_CALLBACK (ev_window_message_area_response_cb),
661                           window);
662         gtk_widget_show (area);
663         ev_window_set_message_area (EV_WINDOW (window), area);
664 }
665
666 static void
667 ev_window_warning_message (GtkWindow *window, const gchar *msg)
668 {
669         GtkWidget *area;
670
671         if (EV_WINDOW (window)->priv->message_area)
672                 return;
673
674         area = ev_message_area_new (GTK_MESSAGE_WARNING,
675                                     msg,
676                                     GTK_STOCK_CLOSE,
677                                     GTK_RESPONSE_CANCEL,
678                                     NULL);
679         
680         g_signal_connect (area, "response",
681                           G_CALLBACK (ev_window_message_area_response_cb),
682                           window);
683         gtk_widget_show (area);
684         ev_window_set_message_area (EV_WINDOW (window), area);
685 }
686
687 static void
688 find_changed_cb (EvDocument *document, int page, EvWindow *ev_window)
689 {
690         ev_window_update_actions (ev_window);
691 }
692
693 static void
694 page_changed_cb (EvPageCache *page_cache,
695                  gint         page,
696                  EvWindow    *ev_window)
697 {
698         ev_window_update_actions (ev_window);
699         
700         if (!ev_window_is_empty (ev_window))
701                 ev_metadata_manager_set_int (ev_window->priv->uri, "page", page);
702 }
703
704 typedef struct _FindTask {
705         const gchar *page_label;
706         gchar *chapter;
707 } FindTask;
708
709 static gboolean
710 ev_window_find_chapter (GtkTreeModel *tree_model,
711                         GtkTreePath  *path,
712                         GtkTreeIter  *iter,
713                         gpointer      data)
714 {
715         FindTask *task = (FindTask *)data;
716         gchar *page_string;
717         
718         gtk_tree_model_get (tree_model, iter,
719                             EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, &page_string, 
720                             -1);
721         
722         if (!page_string)
723                 return FALSE;
724         
725         if (!strcmp (page_string, task->page_label)) {
726                 gtk_tree_model_get (tree_model, iter,
727                                     EV_DOCUMENT_LINKS_COLUMN_MARKUP, &task->chapter, 
728                                     -1);
729                 g_free (page_string);
730                 return TRUE;
731         }
732         
733         g_free (page_string);
734         return FALSE;
735 }
736
737 static void
738 ev_window_add_history (EvWindow *window, gint page, EvLink *link)
739 {
740         gchar *page_label = NULL;
741         gchar *link_title;
742         FindTask find_task;
743         EvLink *real_link;
744         EvLinkAction *action;
745         EvLinkDest *dest;
746         
747         if (window->priv->history == NULL)
748                 return;
749
750         if (!EV_IS_DOCUMENT_LINKS (window->priv->document))
751                 return;
752         
753         if (link) {
754                 action = g_object_ref (ev_link_get_action (link));
755                 dest = ev_link_action_get_dest (action);
756                 page = ev_link_dest_get_page (dest);
757                 page_label = ev_view_page_label_from_dest (EV_VIEW (window->priv->view), dest);
758         } else {
759                 dest = ev_link_dest_new_page (page);
760                 action = ev_link_action_new_dest (dest);
761                 page_label = ev_page_cache_get_page_label (window->priv->page_cache, page);
762         }
763
764         if (!page_label)
765                 return;
766         
767         find_task.page_label = page_label;
768         find_task.chapter = NULL;
769         
770         if (ev_document_links_has_document_links (EV_DOCUMENT_LINKS (window->priv->document))) {
771                 GtkTreeModel *model;
772         
773                 g_object_get (G_OBJECT (window->priv->sidebar_links), "model", &model, NULL);
774                 
775                 if (model) {
776                         gtk_tree_model_foreach (model,
777                                                 ev_window_find_chapter,
778                                                 &find_task);
779         
780                         g_object_unref (model);
781                 }
782         }
783
784         if (find_task.chapter)
785                 link_title = g_strdup_printf (_("Page %s - %s"), page_label, find_task.chapter);
786         else
787                 link_title = g_strdup_printf (_("Page %s"), page_label);
788         
789         real_link = ev_link_new (link_title, action);
790         
791         ev_history_add_link (window->priv->history, real_link);
792
793         g_free (find_task.chapter);
794         g_free (link_title);
795         g_free (page_label);
796         g_object_unref (real_link);
797 }
798
799 static void
800 view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window)
801 {
802         int current_page = ev_page_cache_get_current_page (window->priv->page_cache);
803         
804         ev_window_add_history (window, 0, link);
805         ev_window_add_history (window, current_page, NULL);
806 }
807
808 static void
809 history_changed_cb (EvPageCache *page_cache,
810                     gint         page,
811                     EvWindow    *window)
812 {
813         int current_page = ev_page_cache_get_current_page (window->priv->page_cache);
814
815         ev_window_add_history (window, page, NULL);
816         ev_window_add_history (window, current_page, NULL);
817
818         return;
819 }
820
821 static void
822 update_document_mode (EvWindow *window, EvDocumentMode mode)
823 {
824         if (mode == EV_DOCUMENT_MODE_PRESENTATION) {
825                 ev_window_run_presentation (window);
826         }
827         else if (mode == EV_DOCUMENT_MODE_FULL_SCREEN) {
828                 ev_window_run_fullscreen (window);
829         }
830 }
831
832 static void
833 setup_document_from_metadata (EvWindow *window)
834 {
835         char *uri = window->priv->uri;
836         GValue page = { 0, };
837         gint n_pages;
838         gint new_page;
839
840         /* View the previously shown page, but make sure to not open a document on
841          * the last page, since closing it on the last page most likely means the
842          * user was finished reading the document. In that case, reopening should
843          * show the first page. */
844         if (uri && ev_metadata_manager_get (uri, "page", &page, TRUE)) {
845                 n_pages = ev_page_cache_get_n_pages (window->priv->page_cache);
846                 new_page = CLAMP (g_value_get_int (&page), 0, n_pages - 1);
847                 if (!window->priv->in_reload && new_page == n_pages - 1)
848                         new_page = 0;
849                 ev_page_cache_set_current_page (window->priv->page_cache,
850                                                 new_page);
851                 g_value_unset (&page);
852         }
853 }
854
855 static void
856 setup_chrome_from_metadata (EvWindow *window)
857 {
858         EvChrome chrome = EV_CHROME_NORMAL;
859         GValue show_toolbar = { 0, };
860
861         if (ev_metadata_manager_get (NULL, "show_toolbar", &show_toolbar, FALSE)) {
862                 if (!g_value_get_boolean (&show_toolbar))
863                         chrome &= ~EV_CHROME_TOOLBAR;
864                 g_value_unset (&show_toolbar);
865         }
866         window->priv->chrome = chrome;
867 }
868
869 static void
870 setup_sidebar_from_metadata (EvWindow *window, EvDocument *document)
871 {
872         char *uri = window->priv->uri;
873         GtkWidget *sidebar = window->priv->sidebar;
874         GtkWidget *links = window->priv->sidebar_links;
875         GtkWidget *thumbs = window->priv->sidebar_thumbs;
876         GtkWidget *attachments = window->priv->sidebar_attachments;
877         GValue sidebar_size = { 0, };
878         GValue sidebar_page = { 0, };
879         GValue sidebar_visibility = { 0, };
880
881         if (ev_metadata_manager_get (uri, "sidebar_size", &sidebar_size, FALSE)) {
882                 gtk_paned_set_position (GTK_PANED (window->priv->hpaned),
883                                         g_value_get_int (&sidebar_size));
884                 g_value_unset(&sidebar_size);
885         }
886         
887         if (document && ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page, FALSE)) {
888                 const char *page_id = g_value_get_string (&sidebar_page);
889                 
890                 if (strcmp (page_id, LINKS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) {
891                         ev_sidebar_set_page (EV_SIDEBAR (sidebar), links);
892                 } else if (strcmp (page_id, THUMBNAILS_SIDEBAR_ID) && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) {
893                         ev_sidebar_set_page (EV_SIDEBAR (sidebar), thumbs);
894                 } else if (strcmp (page_id, ATTACHMENTS_SIDEBAR_ID) && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) {
895                         ev_sidebar_set_page (EV_SIDEBAR (sidebar), attachments);
896                 }
897                 g_value_unset (&sidebar_page);
898         } else if (document && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) {
899                 ev_sidebar_set_page (EV_SIDEBAR (sidebar), links);
900         }
901
902         if (ev_metadata_manager_get (uri, "sidebar_visibility", &sidebar_visibility, FALSE)) {
903                 update_chrome_flag (window, EV_CHROME_SIDEBAR, g_value_get_boolean (&sidebar_visibility));
904                 g_value_unset (&sidebar_visibility);
905                 update_chrome_visibility (window);
906         }
907 }
908
909 static void
910 setup_size_from_metadata (EvWindow *window)
911 {
912         char *uri = window->priv->uri;
913         GValue width = { 0, };
914         GValue height = { 0, };
915         GValue width_ratio = { 0, };
916         GValue height_ratio = { 0, };
917         GValue maximized = { 0, };
918         GValue x = { 0, };
919         GValue y = { 0, };
920
921         if (ev_metadata_manager_get (uri, "window_maximized", &maximized, FALSE)) {
922                 if (g_value_get_boolean (&maximized)) {
923                         gtk_window_maximize (GTK_WINDOW (window));
924                         return;
925                 } else {
926                         gtk_window_unmaximize (GTK_WINDOW (window));
927                 }
928                 g_value_unset (&maximized);
929         }
930
931         if (ev_metadata_manager_get (uri, "window_x", &x, TRUE) &&
932             ev_metadata_manager_get (uri, "window_y", &y, TRUE)) {
933                 gtk_window_move (GTK_WINDOW (window), g_value_get_int (&x),
934                                  g_value_get_int (&y));
935                 g_value_unset (&x);
936                 g_value_unset (&y);
937         }
938
939         if (ev_metadata_manager_get (uri, "window_width", &width, TRUE) &&
940             ev_metadata_manager_get (uri, "window_height", &height, TRUE)) {
941                 gtk_window_resize (GTK_WINDOW (window),
942                                    g_value_get_int (&width),
943                                    g_value_get_int (&height));
944                 g_value_unset (&width);
945                 g_value_unset (&height);
946                 return;
947         }
948
949         if (window->priv->page_cache &&
950             ev_metadata_manager_get (uri, "window_width_ratio", &width_ratio, FALSE) &&
951             ev_metadata_manager_get (uri, "window_height_ratio", &height_ratio, FALSE)) {
952                 
953                 gint document_width;
954                 gint document_height;
955                 
956                 GdkScreen *screen;
957                 
958                 gint request_width;
959                 gint request_height;
960
961                 ev_page_cache_get_max_width (window->priv->page_cache, 
962                                              0, 1.0,
963                                              &document_width);
964                 ev_page_cache_get_max_height (window->priv->page_cache, 
965                                              0, 1.0,
966                                              &document_height);                 
967                 
968                 request_width = g_value_get_double (&width_ratio) * document_width;
969                 request_height = g_value_get_double (&height_ratio) * document_height;
970                 
971                 screen = gtk_window_get_screen (GTK_WINDOW (window));
972                 
973                 if (screen) {
974                         request_width = MIN (request_width, gdk_screen_get_width (screen));
975                         request_height = MIN (request_width, gdk_screen_get_height (screen));
976                 }
977                                 
978                 gtk_window_resize (GTK_WINDOW (window),
979                                    request_width,
980                                    request_height);
981                 g_value_unset (&width_ratio);
982                 g_value_unset (&height_ratio);
983         }
984 }
985
986 static void
987 setup_view_from_metadata (EvWindow *window)
988 {
989         EvView *view = EV_VIEW (window->priv->view);
990         char *uri = window->priv->uri;
991         GEnumValue *enum_value;
992         GValue sizing_mode = { 0, };
993         GValue zoom = { 0, };
994         GValue continuous = { 0, };
995         GValue dual_page = { 0, };
996         GValue presentation = { 0, };
997         GValue fullscreen = { 0, };
998         GValue rotation = { 0, };
999         GValue maximized = { 0, };
1000
1001         /* Maximized */
1002         if (ev_metadata_manager_get (uri, "window_maximized", &maximized, FALSE)) {
1003                 if (g_value_get_boolean (&maximized)) {
1004                         gtk_window_maximize (GTK_WINDOW (window));
1005                 } else {
1006                         gtk_window_unmaximize (GTK_WINDOW (window));
1007                 }
1008                 g_value_unset (&maximized);
1009         }
1010
1011         /* Sizing mode */
1012         if (ev_metadata_manager_get (uri, "sizing_mode", &sizing_mode, FALSE)) {
1013                 enum_value = g_enum_get_value_by_nick
1014                         (EV_SIZING_MODE_CLASS, g_value_get_string (&sizing_mode));
1015                 g_value_unset (&sizing_mode);
1016                 ev_view_set_sizing_mode (view, enum_value->value);
1017         }
1018
1019         /* Zoom */
1020         if (ev_metadata_manager_get (uri, "zoom", &zoom, FALSE) &&
1021             ev_view_get_sizing_mode (view) == EV_SIZING_FREE) {
1022                 gdouble zoom_value;
1023
1024                 zoom_value = g_value_get_double (&zoom);
1025                 zoom_value *= get_screen_dpi (GTK_WINDOW (window)) / 72.0;
1026                 ev_view_set_zoom (view, zoom_value, FALSE);
1027                 g_value_unset (&zoom);
1028         }
1029
1030         /* Continuous */
1031         if (ev_metadata_manager_get (uri, "continuous", &continuous, FALSE)) {
1032                 ev_view_set_continuous (view, g_value_get_boolean (&continuous));
1033                 g_value_unset (&continuous);
1034         }
1035
1036         /* Dual page */
1037         if (ev_metadata_manager_get (uri, "dual-page", &dual_page, FALSE)) {
1038                 ev_view_set_dual_page (view, g_value_get_boolean (&dual_page));
1039                 g_value_unset (&dual_page);
1040         }
1041
1042         /* Presentation */
1043         if (ev_metadata_manager_get (uri, "presentation", &presentation, FALSE)) {
1044                 if (g_value_get_boolean (&presentation) && uri) {
1045                         ev_window_run_presentation (window);
1046                 }
1047                 g_value_unset (&presentation);
1048         }
1049
1050         /* Fullscreen */
1051         if (ev_metadata_manager_get (uri, "fullscreen", &fullscreen, FALSE)) {
1052                 if (g_value_get_boolean (&fullscreen) && uri) {
1053                         ev_window_run_fullscreen (window);
1054                 }
1055                 g_value_unset (&fullscreen);
1056         }
1057
1058         /* Rotation */
1059         if (ev_metadata_manager_get (uri, "rotation", &rotation, TRUE)) {
1060                 if (g_value_get_int (&rotation)) {
1061                         switch (g_value_get_int (&rotation)) {
1062                                 case 90:
1063                                         ev_view_set_rotation (view, 90);
1064                                         break;
1065                                 case 180:
1066                                         ev_view_set_rotation (view, 180);
1067                                         break;
1068                                 case 270:
1069                                         ev_view_set_rotation (view, 270);
1070                                         break;
1071                                 default:
1072                                         break;
1073                         }
1074                 }
1075                 g_value_unset (&rotation);
1076         }
1077 }
1078
1079 static void
1080 ev_window_clear_thumbnail_job (EvWindow *ev_window)
1081 {
1082         if (ev_window->priv->thumbnail_job != NULL) {
1083                 ev_job_queue_remove_job (ev_window->priv->thumbnail_job);
1084
1085                 g_signal_handlers_disconnect_by_func (ev_window->priv->thumbnail_job,
1086                                                       ev_window_set_icon_from_thumbnail,
1087                                                       ev_window);
1088                 g_object_unref (ev_window->priv->thumbnail_job);
1089                 ev_window->priv->thumbnail_job = NULL;
1090         }
1091 }
1092
1093 static void
1094 ev_window_set_icon_from_thumbnail (EvJobThumbnail *job,
1095                                    EvWindow       *ev_window)
1096 {
1097         if (job->thumbnail) {
1098                 gtk_window_set_icon (GTK_WINDOW (ev_window),
1099                                      job->thumbnail);
1100         }
1101
1102         ev_window_clear_thumbnail_job (ev_window);
1103 }
1104
1105 static void
1106 ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation)
1107 {
1108         gint page_width, page_height;
1109         gdouble scale;
1110         EvDocument *document = ev_window->priv->document;
1111         
1112         if (!EV_IS_DOCUMENT_THUMBNAILS (document) ||
1113             ev_page_cache_get_n_pages (ev_window->priv->page_cache) <= 0) {
1114                 return;
1115         }
1116         
1117         ev_window_clear_thumbnail_job (ev_window);
1118         
1119         ev_page_cache_get_size (ev_window->priv->page_cache,
1120                                 0, 0, 1.0,
1121                                 &page_width, &page_height);
1122         scale = (gdouble)128 / (gdouble)page_width;
1123         
1124         ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, 0, rotation, scale);
1125         g_signal_connect (ev_window->priv->thumbnail_job, "finished",
1126                           G_CALLBACK (ev_window_set_icon_from_thumbnail),
1127                           ev_window);
1128         ev_job_queue_add_job (EV_JOB (ev_window->priv->thumbnail_job), EV_JOB_PRIORITY_LOW);
1129 }
1130
1131 static gboolean
1132 ev_window_setup_document (EvWindow *ev_window)
1133 {
1134         const EvDocumentInfo *info;
1135         EvDocument *document = ev_window->priv->document;
1136         EvSidebar *sidebar = EV_SIDEBAR (ev_window->priv->sidebar);
1137         GtkAction *action;
1138         
1139         if (EV_IS_DOCUMENT_FIND (document)) {
1140                 g_signal_connect_object (G_OBJECT (document),
1141                                          "find_changed",
1142                                          G_CALLBACK (find_changed_cb),  
1143                                          ev_window, 0);
1144         }
1145         
1146         ev_window_refresh_window_thumbnail (ev_window, 0);
1147
1148         ev_window_set_page_mode (ev_window, PAGE_MODE_DOCUMENT);
1149         ev_window_title_set_document (ev_window->priv->title, document);
1150         ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri);
1151
1152         ev_sidebar_set_document (sidebar, document);
1153
1154         action = gtk_action_group_get_action (ev_window->priv->action_group, PAGE_SELECTOR_ACTION);
1155         ev_page_action_set_document (EV_PAGE_ACTION (action), document);
1156         ev_window_setup_action_sensitivity (ev_window);
1157
1158         if (ev_window->priv->history)
1159                 g_object_unref (ev_window->priv->history);
1160         ev_window->priv->history = ev_history_new ();
1161         action = gtk_action_group_get_action (ev_window->priv->action_group, NAVIGATION_ACTION);
1162         ev_navigation_action_set_history (EV_NAVIGATION_ACTION (action), ev_window->priv->history);
1163         
1164         if (ev_window->priv->properties) {
1165                 ev_properties_dialog_set_document (EV_PROPERTIES_DIALOG (ev_window->priv->properties),
1166                                                    ev_window->priv->document);
1167         }
1168         
1169         info = ev_page_cache_get_info (ev_window->priv->page_cache);
1170         update_document_mode (ev_window, info->mode);
1171
1172         return FALSE;
1173 }
1174
1175 static void
1176 ev_window_set_document (EvWindow *ev_window, EvDocument *document)
1177 {
1178         EvView *view = EV_VIEW (ev_window->priv->view);
1179
1180         if (ev_window->priv->document)
1181                 g_object_unref (ev_window->priv->document);
1182         ev_window->priv->document = g_object_ref (document);
1183
1184         ev_window_set_message_area (ev_window, NULL);
1185         
1186         ev_window->priv->page_cache = ev_page_cache_get (ev_window->priv->document);
1187         g_signal_connect (ev_window->priv->page_cache, "page-changed",
1188                           G_CALLBACK (page_changed_cb), ev_window);
1189         g_signal_connect (ev_window->priv->page_cache, "history-changed",
1190                           G_CALLBACK (history_changed_cb), ev_window);
1191
1192         setup_size_from_metadata (ev_window);
1193         setup_sidebar_from_metadata (ev_window, document);
1194         setup_document_from_metadata (ev_window);
1195
1196         if (ev_page_cache_get_n_pages (ev_window->priv->page_cache) > 0) {
1197                 ev_view_set_document (view, document);
1198         } else {
1199                 ev_window_warning_message (GTK_WINDOW (ev_window),
1200                                            _("The document contains no pages"));
1201         }
1202
1203         g_idle_add ((GSourceFunc)ev_window_setup_document, ev_window);
1204 }
1205
1206 static void
1207 ev_window_document_changed (EvWindow *ev_window,
1208                             gpointer  user_data)
1209 {
1210         ev_window_reload_document (ev_window);
1211 }
1212
1213 static void
1214 password_dialog_response (GtkWidget *password_dialog,
1215                           gint       response_id,
1216                           EvWindow  *ev_window)
1217 {
1218         char *password;
1219         
1220         if (response_id == GTK_RESPONSE_OK) {
1221
1222                 password = ev_password_dialog_get_password (EV_PASSWORD_DIALOG (password_dialog));
1223                 if (password) {
1224                         ev_document_doc_mutex_lock ();
1225                         ev_document_security_set_password (EV_DOCUMENT_SECURITY (ev_window->priv->load_job->document),
1226                                                            password);
1227                         ev_document_doc_mutex_unlock ();
1228                 }
1229                 g_free (password);
1230
1231                 ev_password_dialog_save_password (EV_PASSWORD_DIALOG (password_dialog));
1232
1233                 ev_window_title_set_type (ev_window->priv->title, EV_WINDOW_TITLE_DOCUMENT);
1234                 ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
1235                 
1236                 gtk_widget_destroy (password_dialog);
1237                         
1238                 return;
1239         }
1240
1241         gtk_widget_set_sensitive (ev_window->priv->password_view, TRUE);
1242         gtk_widget_destroy (password_dialog);
1243 }
1244
1245 /* Called either by ev_window_load_job_cb or by the "unlock" callback on the
1246  * password_view page.  It assumes that ev_window->priv->password_* has been set
1247  * correctly.  These are cleared by password_dialog_response() */
1248
1249 static void
1250 ev_window_popup_password_dialog (EvWindow *ev_window)
1251 {
1252         g_assert (ev_window->priv->load_job);
1253
1254         gtk_widget_set_sensitive (ev_window->priv->password_view, FALSE);
1255
1256         ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri);
1257         ev_window_title_set_type (ev_window->priv->title, EV_WINDOW_TITLE_PASSWORD);
1258
1259         if (ev_window->priv->password_dialog == NULL) {
1260                 ev_window->priv->password_dialog =
1261                         g_object_new (EV_TYPE_PASSWORD_DIALOG, "uri", ev_window->priv->uri, NULL);
1262                 gtk_window_set_transient_for (GTK_WINDOW (ev_window->priv->password_dialog), GTK_WINDOW (ev_window));
1263
1264                 g_object_add_weak_pointer (G_OBJECT (ev_window->priv->password_dialog),
1265                                            (gpointer) &(ev_window->priv->password_dialog));
1266                 g_signal_connect (ev_window->priv->password_dialog,
1267                                   "response",
1268                                   G_CALLBACK (password_dialog_response),
1269                                   ev_window);
1270                 gtk_widget_show (ev_window->priv->password_dialog);
1271         } else {
1272                 ev_password_dialog_set_bad_pass (EV_PASSWORD_DIALOG (ev_window->priv->password_dialog));
1273         }
1274 }
1275
1276 static void
1277 ev_window_clear_load_job (EvWindow *ev_window)
1278 {
1279         if (ev_window->priv->load_job != NULL) {
1280                 
1281                 if (!ev_window->priv->load_job->finished)
1282                         ev_job_queue_remove_job (ev_window->priv->load_job);
1283                 
1284                 g_signal_handlers_disconnect_by_func (ev_window->priv->load_job, ev_window_load_job_cb, ev_window);
1285                 g_object_unref (ev_window->priv->load_job);
1286                 ev_window->priv->load_job = NULL;
1287         }
1288 }
1289
1290 static void
1291 ev_window_clear_reload_job (EvWindow *ev_window)
1292 {
1293         if (ev_window->priv->reload_job != NULL) {
1294                 
1295                 if (!ev_window->priv->reload_job->finished)
1296                         ev_job_queue_remove_job (ev_window->priv->reload_job);
1297                 
1298                 g_signal_handlers_disconnect_by_func (ev_window->priv->reload_job, ev_window_reload_job_cb, ev_window);
1299                 g_object_unref (ev_window->priv->reload_job);
1300                 ev_window->priv->reload_job = NULL;
1301         }
1302 }
1303
1304 static void
1305 ev_window_clear_local_uri (EvWindow *ev_window)
1306 {
1307         if (ev_window->priv->local_uri) {
1308                 ev_tmp_uri_unlink (ev_window->priv->local_uri);
1309                 g_free (ev_window->priv->local_uri);
1310                 ev_window->priv->local_uri = NULL;
1311         }
1312 }
1313
1314 static void
1315 ev_window_clear_print_settings_file (EvWindow *ev_window)
1316 {
1317         if (ev_window->priv->print_settings_file) {
1318                 g_unlink (ev_window->priv->print_settings_file);
1319                 g_free (ev_window->priv->print_settings_file);
1320                 ev_window->priv->print_settings_file = NULL;
1321         }
1322 }
1323
1324 static void
1325 ev_window_clear_temp_file (EvWindow *ev_window)
1326 {
1327         GFile *file, *tempdir;
1328
1329         if (!ev_window->priv->uri)
1330                 return;
1331
1332         file = g_file_new_for_uri (ev_window->priv->uri);
1333         tempdir = g_file_new_for_path (g_get_tmp_dir ());
1334
1335         if (g_file_has_prefix (file, tempdir)) {
1336                 g_file_delete (file, NULL, NULL);
1337         }
1338
1339         g_object_unref (file);
1340         g_object_unref (tempdir);
1341 }
1342
1343 /* This callback will executed when load job will be finished.
1344  *
1345  * Since the flow of the error dialog is very confusing, we assume that both
1346  * document and uri will go away after this function is called, and thus we need
1347  * to ref/dup them.  Additionally, it needs to clear
1348  * ev_window->priv->password_{uri,document}, and thus people who call this
1349  * function should _not_ necessarily expect those to exist after being
1350  * called. */
1351 static void
1352 ev_window_load_job_cb  (EvJobLoad *job,
1353                         gpointer data)
1354 {
1355         EvWindow *ev_window = EV_WINDOW (data);
1356         EvDocument *document = EV_JOB (job)->document;
1357
1358         g_assert (job->uri);
1359
1360         ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
1361
1362         /* Success! */
1363         if (job->error == NULL) {
1364                 ev_window_set_document (ev_window, document);
1365                 
1366                 if (job->mode != EV_WINDOW_MODE_PREVIEW) {
1367                         setup_view_from_metadata (ev_window);
1368                 }
1369
1370                 if (!ev_window->priv->unlink_temp_file) {
1371                         ev_window_add_recent (ev_window, ev_window->priv->uri);
1372                 }
1373
1374                 if (job->dest) {
1375                         EvLink *link;
1376                         EvLinkAction *link_action;
1377         
1378                         link_action = ev_link_action_new_dest (g_object_ref (job->dest));
1379                         link = ev_link_new (NULL, link_action);
1380                         ev_view_handle_link (EV_VIEW (ev_window->priv->view), link);
1381                         g_object_unref (link);
1382                 }
1383
1384                 switch (job->mode) {
1385                         case EV_WINDOW_MODE_FULLSCREEN:
1386                                 ev_window_run_fullscreen (ev_window);
1387                                 break;
1388                         case EV_WINDOW_MODE_PRESENTATION:
1389                                 ev_window_run_presentation (ev_window);
1390                                 break;
1391                         case EV_WINDOW_MODE_PREVIEW:
1392                                 ev_window_run_preview (ev_window);
1393                                 break;
1394                         default:
1395                                 break;
1396                 }
1397
1398                 if (job->search_string && EV_IS_DOCUMENT_FIND (document)) {
1399                         ev_window_cmd_edit_find (NULL, ev_window);
1400                         egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar),
1401                                                         job->search_string);
1402                 }
1403
1404                 /* Create a monitor for the document */
1405                 ev_window->priv->monitor = ev_file_monitor_new (job->uri);
1406                 g_signal_connect_swapped (G_OBJECT (ev_window->priv->monitor), "changed",
1407                                           G_CALLBACK (ev_window_document_changed),
1408                                           ev_window);
1409                 
1410                 ev_window_clear_load_job (ev_window);
1411                 return;
1412         }
1413
1414         if (job->error->domain == EV_DOCUMENT_ERROR &&
1415             job->error->code == EV_DOCUMENT_ERROR_ENCRYPTED) {
1416                 GFile *file;
1417                 gchar *base_name;
1418
1419                 setup_view_from_metadata (ev_window);
1420
1421                 file = g_file_new_for_uri (job->uri);
1422                 base_name = g_file_get_basename (file);
1423                 ev_password_view_set_file_name (EV_PASSWORD_VIEW (ev_window->priv->password_view),
1424                                                 base_name);
1425                 g_object_unref (file);
1426                 g_free (base_name);
1427                 ev_window_set_page_mode (ev_window, PAGE_MODE_PASSWORD);
1428                 
1429                 ev_window_popup_password_dialog (ev_window);
1430         } else {
1431                 ev_window_error_message (GTK_WINDOW (ev_window), 
1432                                          _("Unable to open document"),
1433                                          job->error);
1434                 ev_window_clear_load_job (ev_window);
1435         }       
1436 }
1437
1438 static void
1439 ev_window_reload_job_cb (EvJobLoad *job,
1440                          EvWindow  *ev_window)
1441 {
1442         GtkWidget *widget;
1443         
1444         if (job->error) {
1445                 ev_window_clear_reload_job (ev_window);
1446                 ev_window->priv->in_reload = FALSE;
1447                 return;
1448         }
1449
1450         ev_window_set_document (ev_window, EV_JOB (job)->document);
1451
1452         /* Restart the search after reloading */
1453         widget = gtk_window_get_focus (GTK_WINDOW (ev_window));
1454         if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) {
1455                 find_bar_search_changed_cb (EGG_FIND_BAR (ev_window->priv->find_bar),
1456                                             NULL, ev_window);
1457         }
1458
1459         ev_window_clear_reload_job (ev_window);
1460         ev_window->priv->in_reload = FALSE;
1461 }
1462
1463 /**
1464  * ev_window_get_uri:
1465  * @ev_window: The instance of the #EvWindow.
1466  *
1467  * It returns the uri of the document showed in the #EvWindow.
1468  *
1469  * Returns: the uri of the document showed in the #EvWindow.
1470  */
1471 const char *
1472 ev_window_get_uri (EvWindow *ev_window)
1473 {
1474         return ev_window->priv->uri;
1475 }
1476
1477 /**
1478  * ev_window_close_dialogs:
1479  * @ev_window: The window where dialogs will be closed.
1480  *
1481  * It looks for password, print and properties dialogs and closes them and
1482  * frees them from memory. If there is any print job it does free it too.
1483  */
1484 static void
1485 ev_window_close_dialogs (EvWindow *ev_window)
1486 {
1487         if (ev_window->priv->password_dialog)
1488                 gtk_widget_destroy (ev_window->priv->password_dialog);
1489         ev_window->priv->password_dialog = NULL;
1490         
1491         if (ev_window->priv->print_dialog)
1492                 gtk_widget_destroy (ev_window->priv->print_dialog);
1493         ev_window->priv->print_dialog = NULL;
1494         
1495         if (ev_window->priv->properties)
1496                 gtk_widget_destroy (ev_window->priv->properties);
1497         ev_window->priv->properties = NULL;
1498 }
1499
1500 static void
1501 ev_window_load_remote_failed (EvWindow *ev_window,
1502                               GError   *error)
1503 {
1504         ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
1505         ev_window->priv->in_reload = FALSE;
1506         ev_window_error_message (GTK_WINDOW (ev_window),
1507                                  _("Unable to open document"),
1508                                  error);
1509         g_free (ev_window->priv->local_uri);
1510         ev_window->priv->local_uri = NULL;
1511 }
1512
1513 static void
1514 mount_volume_ready_cb (GFile        *source,
1515                        GAsyncResult *async_result,
1516                        EvWindow     *ev_window)
1517 {
1518         GError *error = NULL;
1519
1520         g_file_mount_enclosing_volume_finish (source, async_result, &error);
1521
1522         if (error) {
1523                 ev_window_load_remote_failed (ev_window, error);
1524                 g_object_unref (source);
1525                 g_error_free (error);
1526         } else {
1527                 /* Volume successfully mounted,
1528                    try opening the file again */
1529                 ev_window_load_file_remote (ev_window, source);
1530         }
1531 }
1532
1533 static void
1534 window_open_file_copy_ready_cb (GFile        *source,
1535                                 GAsyncResult *async_result,
1536                                 EvWindow     *ev_window)
1537 {
1538         GError *error = NULL;
1539         
1540         g_file_copy_finish (source, async_result, &error);
1541         if (!error) {
1542                 ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
1543                 g_object_unref (source);
1544                 
1545                 return;
1546         }
1547
1548         if (error->domain == G_IO_ERROR &&
1549             error->code == G_IO_ERROR_NOT_MOUNTED) {
1550                 GMountOperation *operation;
1551
1552                 operation = ev_mount_operation_new (GTK_WINDOW (ev_window));
1553                 g_file_mount_enclosing_volume (source,
1554                                                G_MOUNT_MOUNT_NONE,
1555                                                operation, NULL,
1556                                                (GAsyncReadyCallback)mount_volume_ready_cb,
1557                                                ev_window);
1558                 g_object_unref (operation);
1559         } else {
1560                 ev_window_load_remote_failed (ev_window, error);
1561                 g_object_unref (source);
1562         }
1563         
1564         g_error_free (error);
1565 }
1566
1567 static void
1568 ev_window_load_file_remote (EvWindow  *ev_window,
1569                             GFile     *source_file)
1570 {
1571         GFile *target_file;
1572         
1573         if (!ev_window->priv->local_uri) {
1574                 gchar *tmp_name;
1575                 gchar *base_name;
1576
1577                 /* We'd like to keep extension of source uri since
1578                  * it helps to resolve some mime types, say cbz */
1579                 tmp_name = ev_tmp_filename (NULL);
1580                 base_name = g_file_get_basename (source_file);
1581                 ev_window->priv->local_uri = g_strconcat ("file:", tmp_name, "-",
1582                                                           base_name, NULL);
1583                 ev_job_load_set_uri (EV_JOB_LOAD (ev_window->priv->load_job),
1584                                      ev_window->priv->local_uri);
1585                 g_free (base_name);
1586                 g_free (tmp_name);
1587         }
1588         
1589         target_file = g_file_new_for_uri (ev_window->priv->local_uri);
1590         g_file_copy_async (source_file, target_file,
1591                            0, G_PRIORITY_DEFAULT, NULL,
1592                            NULL, NULL, /* no progress callback */
1593                            (GAsyncReadyCallback) window_open_file_copy_ready_cb,
1594                            ev_window);
1595         g_object_unref (target_file);
1596 }
1597
1598 void
1599 ev_window_open_uri (EvWindow       *ev_window,
1600                     const char     *uri,
1601                     EvLinkDest     *dest,
1602                     EvWindowRunMode mode,
1603                     const gchar    *search_string, 
1604                     gboolean        unlink_temp_file,
1605                     const gchar    *print_settings)
1606 {
1607         GFile *source_file;
1608
1609         ev_window->priv->in_reload = FALSE;
1610         
1611         if (ev_window->priv->uri &&
1612             g_ascii_strcasecmp (ev_window->priv->uri, uri) == 0) {
1613                 ev_window_reload_document (ev_window);
1614                 return;
1615         }
1616
1617         if (ev_window->priv->monitor) {
1618                 g_object_unref (ev_window->priv->monitor);
1619                 ev_window->priv->monitor = NULL;
1620         }
1621         
1622         ev_window_close_dialogs (ev_window);
1623         ev_window_clear_load_job (ev_window);
1624         ev_window_clear_local_uri (ev_window);
1625         ev_window_clear_print_settings_file (ev_window);
1626         ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE);
1627
1628         ev_window->priv->unlink_temp_file = unlink_temp_file;
1629
1630         if (mode == EV_WINDOW_MODE_PREVIEW) {
1631                 ev_window->priv->print_settings_file = print_settings ? 
1632                         g_strdup (print_settings) : NULL;
1633         }
1634
1635         if (ev_window->priv->uri)
1636                 g_free (ev_window->priv->uri);
1637         ev_window->priv->uri = g_strdup (uri);
1638
1639         setup_size_from_metadata (ev_window);
1640         
1641         ev_window->priv->load_job = ev_job_load_new (uri, dest, mode, search_string);
1642         g_signal_connect (ev_window->priv->load_job,
1643                           "finished",
1644                           G_CALLBACK (ev_window_load_job_cb),
1645                           ev_window);
1646
1647         source_file = g_file_new_for_uri (uri);
1648         if (!g_file_is_native (source_file) && !ev_window->priv->local_uri) {
1649                 ev_window_load_file_remote (ev_window, source_file);
1650         } else {
1651                 g_object_unref (source_file);
1652                 ev_job_queue_add_job (ev_window->priv->load_job, EV_JOB_PRIORITY_HIGH);
1653         }
1654 }
1655
1656 static void
1657 ev_window_reload_document (EvWindow *ev_window)
1658 {
1659         const gchar *uri;
1660
1661         ev_window_clear_reload_job (ev_window);
1662         ev_window->priv->in_reload = TRUE;
1663         
1664         uri = ev_window->priv->local_uri ? ev_window->priv->local_uri : ev_window->priv->uri;
1665         ev_window->priv->reload_job = ev_job_load_new (uri, NULL, 0, NULL);
1666         g_signal_connect (ev_window->priv->reload_job, "finished",
1667                           G_CALLBACK (ev_window_reload_job_cb),
1668                           ev_window);
1669         ev_job_queue_add_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_LOW);
1670 }
1671
1672 static void
1673 file_open_dialog_response_cb (GtkWidget *chooser,
1674                               gint       response_id,
1675                               EvWindow  *ev_window)
1676 {
1677         gchar *uri;
1678
1679         if (response_id == GTK_RESPONSE_OK) {
1680                 GSList *uris;
1681
1682                 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (chooser));
1683
1684                 ev_application_open_uri_list (EV_APP, uris,
1685                                               gtk_window_get_screen (GTK_WINDOW (ev_window)),
1686                                               GDK_CURRENT_TIME);
1687         
1688                 g_slist_foreach (uris, (GFunc)g_free, NULL);    
1689                 g_slist_free (uris);
1690         }
1691
1692         uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (chooser));
1693         ev_application_set_chooser_uri (EV_APP, uri);
1694         g_free (uri);
1695
1696         gtk_widget_destroy (chooser);
1697 }
1698
1699 static void
1700 ev_window_cmd_file_open (GtkAction *action, EvWindow *window)
1701 {
1702         GtkWidget *chooser;
1703
1704         chooser = gtk_file_chooser_dialog_new (_("Open Document"),
1705                                                GTK_WINDOW (window),
1706                                                GTK_FILE_CHOOSER_ACTION_OPEN,
1707                                                GTK_STOCK_CANCEL,
1708                                                GTK_RESPONSE_CANCEL,
1709                                                GTK_STOCK_OPEN, GTK_RESPONSE_OK,
1710                                                NULL);
1711
1712         ev_document_factory_add_filters (chooser, NULL);
1713         gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser), TRUE);
1714         gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), FALSE);
1715         if (ev_application_get_chooser_uri (EV_APP) != NULL) {
1716                 gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (chooser),
1717                                           ev_application_get_chooser_uri (EV_APP));
1718         } else if (window->priv->uri != NULL) {
1719                 gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (chooser),
1720                                           window->priv->uri);
1721         } else {
1722                 const gchar *folder;
1723
1724                 folder = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
1725                 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
1726                                                      folder ? folder : g_get_home_dir ());
1727         }
1728         
1729         g_signal_connect (chooser, "response",
1730                           G_CALLBACK (file_open_dialog_response_cb),
1731                           window);
1732
1733         gtk_widget_show (chooser);
1734 }
1735
1736 static gchar *
1737 ev_window_create_tmp_symlink (const gchar *filename, GError **error)
1738 {
1739         gchar *tmp_filename = NULL;
1740         gchar *name;
1741         gint   res;
1742         guint  i = 0;
1743
1744         name = g_path_get_basename (filename);
1745         
1746         do {
1747                 gchar *basename;
1748
1749                 if (tmp_filename)
1750                         g_free (tmp_filename);
1751
1752                 basename = g_strdup_printf ("%s-%d", name, i++);
1753                 tmp_filename = g_build_filename (ev_tmp_dir (),
1754                                                  basename, NULL);
1755                 
1756                 g_free (basename);
1757         } while ((res = symlink (filename, tmp_filename)) != 0 && errno == EEXIST);
1758
1759         g_free (name);
1760         
1761         if (res != 0 && errno != EEXIST) {
1762                 if (error) {
1763                         *error = g_error_new (G_FILE_ERROR,
1764                                               g_file_error_from_errno (errno),
1765                                               _("Couldn't create symlink “%s”: %s"),
1766                                               tmp_filename, strerror (errno));
1767                 }
1768
1769                 g_free (tmp_filename);
1770
1771                 return NULL;
1772         }
1773         
1774         return tmp_filename;
1775 }
1776
1777 static void
1778 ev_window_cmd_file_open_copy_at_dest (EvWindow *window, EvLinkDest *dest)
1779 {
1780         GError      *error = NULL;
1781         gchar       *symlink_uri;
1782         gchar       *old_filename;
1783         gchar       *new_filename;
1784         const gchar *uri_unc;
1785
1786         uri_unc = g_object_get_data (G_OBJECT (window->priv->document),
1787                                      "uri-uncompressed");
1788         old_filename = g_filename_from_uri (uri_unc ? uri_unc : window->priv->uri,
1789                                             NULL, NULL);
1790         new_filename = ev_window_create_tmp_symlink (old_filename, &error);
1791
1792         if (error) {
1793                 ev_window_error_message (GTK_WINDOW (window),
1794                                          _("Cannot open a copy."),
1795                                          error);
1796
1797                 g_error_free (error);
1798                 g_free (old_filename);
1799                 g_free (new_filename);
1800
1801                 return;
1802         }
1803                 
1804         g_free (old_filename);
1805
1806         symlink_uri = g_filename_to_uri (new_filename, NULL, NULL);
1807         g_free (new_filename);
1808
1809         ev_application_open_uri_at_dest (EV_APP,
1810                                          symlink_uri,
1811                                          gtk_window_get_screen (GTK_WINDOW (window)),
1812                                          dest,
1813                                          0,
1814                                          NULL, 
1815                                          TRUE,
1816                                          NULL,
1817                                          GDK_CURRENT_TIME);
1818         g_free (symlink_uri);
1819 }
1820
1821 static void
1822 ev_window_cmd_file_open_copy (GtkAction *action, EvWindow *window)
1823 {
1824         EvPageCache *page_cache;
1825         EvLinkDest  *dest;
1826         gint         current_page;
1827
1828         page_cache = ev_page_cache_get (window->priv->document);
1829         current_page = ev_page_cache_get_current_page (page_cache);
1830         
1831         dest = ev_link_dest_new_page (current_page);
1832         ev_window_cmd_file_open_copy_at_dest (window, dest);
1833         g_object_unref (dest);
1834 }
1835
1836 static void
1837 ev_window_cmd_recent_file_activate (GtkAction *action,
1838                                     EvWindow  *window)
1839 {
1840         GtkRecentInfo *info;
1841         const gchar   *uri;
1842
1843         info = g_object_get_data (G_OBJECT (action), "gtk-recent-info");
1844         g_assert (info != NULL);
1845         
1846         uri = gtk_recent_info_get_uri (info);
1847         
1848         ev_application_open_uri_at_dest (EV_APP, uri,
1849                                          gtk_window_get_screen (GTK_WINDOW (window)),
1850                                          NULL, 0, NULL, FALSE, NULL, 
1851                                          GDK_CURRENT_TIME);
1852 }
1853
1854 static void
1855 ev_window_open_recent_action_item_activated (EvOpenRecentAction *action,
1856                                              const gchar        *uri,
1857                                              EvWindow           *window)
1858 {
1859         ev_application_open_uri_at_dest (EV_APP, uri,
1860                                          gtk_window_get_screen (GTK_WINDOW (window)),
1861                                          NULL, 0, NULL, FALSE, NULL, 
1862                                          GDK_CURRENT_TIME);
1863 }
1864
1865 static void
1866 ev_window_add_recent (EvWindow *window, const char *filename)
1867 {
1868         gtk_recent_manager_add_item (window->priv->recent_manager, filename);
1869 }
1870
1871 static gint
1872 compare_recent_items (GtkRecentInfo *a, GtkRecentInfo *b)
1873 {
1874         gboolean     has_ev_a, has_ev_b;
1875         const gchar *evince = g_get_application_name ();
1876
1877         has_ev_a = gtk_recent_info_has_application (a, evince);
1878         has_ev_b = gtk_recent_info_has_application (b, evince);
1879         
1880         if (has_ev_a && has_ev_b) {
1881                 time_t time_a, time_b;
1882
1883                 time_a = gtk_recent_info_get_modified (a);
1884                 time_b = gtk_recent_info_get_modified (b);
1885
1886                 return (time_b - time_a);
1887         } else if (has_ev_a) {
1888                 return -1;
1889         } else if (has_ev_b) {
1890                 return 1;
1891         }
1892
1893         return 0;
1894 }
1895
1896 /*
1897  * Doubles underscore to avoid spurious menu accels.
1898  */
1899 static gchar * 
1900 ev_window_get_recent_file_label (gint index, const gchar *filename)
1901 {
1902         GString *str;
1903         gint length;
1904         const gchar *p;
1905         const gchar *end;
1906         gboolean is_rtl;
1907         
1908         is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
1909
1910         g_return_val_if_fail (filename != NULL, NULL);
1911         
1912         length = strlen (filename);
1913         str = g_string_sized_new (length + 10);
1914         g_string_printf (str, "%s_%d.  ", is_rtl ? "\xE2\x80\x8F" : "", index);
1915
1916         p = filename;
1917         end = filename + length;
1918  
1919         while (p != end) {
1920                 const gchar *next;
1921                 next = g_utf8_next_char (p);
1922  
1923                 switch (*p) {
1924                         case '_':
1925                                 g_string_append (str, "__");
1926                                 break;
1927                         default:
1928                                 g_string_append_len (str, p, next - p);
1929                                 break;
1930                 }
1931  
1932                 p = next;
1933         }
1934  
1935         return g_string_free (str, FALSE);
1936 }
1937
1938 static void
1939 ev_window_setup_recent (EvWindow *ev_window)
1940 {
1941         GList        *items, *l;
1942         guint         n_items = 0;
1943         const gchar  *evince = g_get_application_name ();
1944         static guint  i = 0;
1945
1946         if (ev_window->priv->recent_ui_id > 0) {
1947                 gtk_ui_manager_remove_ui (ev_window->priv->ui_manager,
1948                                           ev_window->priv->recent_ui_id);
1949                 gtk_ui_manager_ensure_update (ev_window->priv->ui_manager);
1950         }
1951         ev_window->priv->recent_ui_id = gtk_ui_manager_new_merge_id (ev_window->priv->ui_manager);
1952
1953         if (ev_window->priv->recent_action_group) {
1954                 gtk_ui_manager_remove_action_group (ev_window->priv->ui_manager,
1955                                                     ev_window->priv->recent_action_group);
1956                 g_object_unref (ev_window->priv->recent_action_group);
1957         }
1958         ev_window->priv->recent_action_group = gtk_action_group_new ("RecentFilesActions");
1959         gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
1960                                             ev_window->priv->recent_action_group, 0);
1961
1962         items = gtk_recent_manager_get_items (ev_window->priv->recent_manager);
1963         items = g_list_sort (items, (GCompareFunc) compare_recent_items);
1964
1965         for (l = items; l && l->data; l = g_list_next (l)) {
1966                 GtkRecentInfo *info;
1967                 GtkAction     *action;
1968                 gchar         *action_name;
1969                 gchar         *label;
1970
1971                 info = (GtkRecentInfo *) l->data;
1972
1973                 if (!gtk_recent_info_has_application (info, evince) ||
1974                     (gtk_recent_info_is_local (info) && !gtk_recent_info_exists (info)))
1975                         continue;
1976
1977                 action_name = g_strdup_printf ("RecentFile%u", i++);
1978                 label = ev_window_get_recent_file_label (
1979                         n_items + 1, gtk_recent_info_get_display_name (info));
1980                 
1981                 action = g_object_new (GTK_TYPE_ACTION,
1982                                        "name", action_name,
1983                                        "label", label,
1984                                        NULL);
1985
1986                 g_object_set_data_full (G_OBJECT (action),
1987                                         "gtk-recent-info",
1988                                         gtk_recent_info_ref (info),
1989                                         (GDestroyNotify) gtk_recent_info_unref);
1990                 
1991                 g_signal_connect (G_OBJECT (action), "activate",
1992                                   G_CALLBACK (ev_window_cmd_recent_file_activate),
1993                                   (gpointer) ev_window);
1994
1995                 gtk_action_group_add_action (ev_window->priv->recent_action_group,
1996                                              action);
1997                 g_object_unref (action);
1998
1999                 gtk_ui_manager_add_ui (ev_window->priv->ui_manager,
2000                                        ev_window->priv->recent_ui_id,
2001                                        "/MainMenu/FileMenu/RecentFilesMenu",
2002                                        label,
2003                                        action_name,
2004                                        GTK_UI_MANAGER_MENUITEM,
2005                                        FALSE);
2006                 g_free (action_name);
2007                 g_free (label);
2008
2009                 if (++n_items == 5)
2010                         break;
2011         }
2012         
2013         g_list_foreach (items, (GFunc) gtk_recent_info_unref, NULL);
2014         g_list_free (items);
2015 }
2016
2017 static void
2018 window_save_file_copy_ready_cb (GFile        *src,
2019                                 GAsyncResult *async_result,
2020                                 GFile        *dst)
2021 {
2022         EvWindow  *window;
2023         GtkWidget *dialog;
2024         gchar     *name;
2025         GError    *error = NULL;
2026
2027         if (g_file_copy_finish (src, async_result, &error)) {
2028                 ev_tmp_file_unlink (src);
2029                 return;
2030         }
2031
2032         window = g_object_get_data (G_OBJECT (dst), "ev-window");
2033         name = g_file_get_basename (dst);
2034         dialog = gtk_message_dialog_new (GTK_WINDOW (window),
2035                                          GTK_DIALOG_DESTROY_WITH_PARENT,
2036                                          GTK_MESSAGE_ERROR,
2037                                          GTK_BUTTONS_CLOSE,
2038                                          _("The file could not be saved as “%s”."),
2039                                          name);
2040         gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
2041                                                   "%s", error->message);
2042         g_signal_connect (dialog, "response",
2043                           G_CALLBACK (gtk_widget_destroy),
2044                           NULL);
2045         gtk_widget_show (dialog);
2046         ev_tmp_file_unlink (src);
2047
2048         g_free (name);
2049         g_error_free (error);
2050 }
2051
2052 static void
2053 ev_window_save_remote (EvWindow *ev_window,
2054                        GFile    *src,
2055                        GFile    *dst)
2056 {
2057         g_object_set_data (G_OBJECT (dst), "ev-window", ev_window);
2058         g_file_copy_async (src, dst,
2059                            G_FILE_COPY_OVERWRITE,
2060                            G_PRIORITY_DEFAULT, NULL,
2061                            NULL, NULL, /* no progress callback */
2062                            (GAsyncReadyCallback) window_save_file_copy_ready_cb,
2063                            dst);                
2064 }
2065
2066 static void
2067 ev_window_clear_save_job (EvWindow *ev_window)
2068 {
2069         if (ev_window->priv->save_job != NULL) {
2070                 if (!ev_window->priv->save_job->finished)
2071                         ev_job_queue_remove_job (ev_window->priv->save_job);
2072                 
2073                 g_signal_handlers_disconnect_by_func (ev_window->priv->save_job,
2074                                                       ev_window_save_job_cb,
2075                                                       ev_window);
2076                 g_object_unref (ev_window->priv->save_job);
2077                 ev_window->priv->save_job = NULL;
2078         }
2079 }
2080
2081 static void
2082 ev_window_save_job_cb (EvJobSave *job,
2083                        EvWindow  *window)
2084 {
2085         if (job->error) {
2086                 gchar *msg;
2087                 
2088                 msg = g_strdup_printf (_("The file could not be saved as “%s”."), job->uri);
2089                 ev_window_error_message (GTK_WINDOW (window), msg, job->error);
2090                 g_free (msg);
2091         }
2092
2093         ev_window_clear_save_job (window);
2094 }
2095
2096 static void
2097 file_save_dialog_response_cb (GtkWidget *fc,
2098                               gint       response_id,
2099                               EvWindow  *ev_window)
2100 {
2101         gchar *uri;
2102         
2103         if (response_id != GTK_RESPONSE_OK) {
2104                 gtk_widget_destroy (fc);
2105                 return;
2106         }
2107         
2108         uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
2109         
2110         ev_window_clear_save_job (ev_window);
2111         ev_window->priv->save_job = ev_job_save_new (ev_window->priv->document,
2112                                                      uri, ev_window->priv->uri);
2113         g_signal_connect (ev_window->priv->save_job, "finished",
2114                           G_CALLBACK (ev_window_save_job_cb),
2115                           ev_window);
2116         /* The priority doesn't matter for this job */
2117         ev_job_queue_add_job (ev_window->priv->save_job, EV_JOB_PRIORITY_LOW);
2118
2119         g_free (uri);
2120
2121         gtk_widget_destroy (fc);
2122 }
2123
2124 static void
2125 ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window)
2126 {
2127         GtkWidget *fc;
2128         gchar *base_name;
2129         GFile *file;
2130         const gchar *folder;
2131
2132         fc = gtk_file_chooser_dialog_new (
2133                 _("Save a Copy"),
2134                 GTK_WINDOW (ev_window), GTK_FILE_CHOOSER_ACTION_SAVE,
2135                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
2136                 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
2137                 NULL);
2138
2139         ev_document_factory_add_filters (fc, ev_window->priv->document);
2140         gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK);
2141
2142         gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (fc), FALSE);
2143         gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE);
2144         file = g_file_new_for_uri (ev_window->priv->uri);
2145         base_name = g_file_get_basename (file);
2146         gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (fc), base_name);
2147         
2148         folder = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
2149         gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (fc),
2150                                              folder ? folder : g_get_home_dir ());
2151         
2152         g_object_unref (file);
2153         g_free (base_name);
2154         
2155         g_signal_connect (fc, "response",
2156                           G_CALLBACK (file_save_dialog_response_cb),
2157                           ev_window);
2158
2159         gtk_widget_show (fc);
2160 }
2161
2162 static void
2163 ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup,
2164                                     EvWindow     *window)
2165 {
2166         /* Dialog was canceled */
2167         if (!page_setup)
2168                 return;
2169
2170         if (window->priv->print_page_setup)
2171                 g_object_unref (window->priv->print_page_setup);
2172         window->priv->print_page_setup = g_object_ref (page_setup);
2173 }
2174
2175 static void
2176 ev_window_cmd_file_print_setup (GtkAction *action, EvWindow *ev_window)
2177 {
2178         gtk_print_run_page_setup_dialog_async (
2179                 GTK_WINDOW (ev_window),
2180                 ev_window->priv->print_page_setup,
2181                 ev_window->priv->print_settings,
2182                 (GtkPageSetupDoneFunc) ev_window_print_page_setup_done_cb,
2183                 ev_window);
2184 }
2185
2186 static void
2187 ev_window_clear_print_job (EvWindow *window)
2188 {
2189         if (window->priv->print_job) {
2190                 if (!window->priv->print_job->finished)
2191                         ev_job_queue_remove_job (window->priv->print_job);
2192
2193                 g_signal_handlers_disconnect_by_func (window->priv->print_job,
2194                                                       ev_window_print_job_cb,
2195                                                       window);
2196                 g_object_unref (window->priv->print_job);
2197                 window->priv->print_job = NULL;
2198         }
2199
2200         if (window->priv->gtk_print_job) {
2201                 g_object_unref (window->priv->gtk_print_job);
2202                 window->priv->gtk_print_job = NULL;
2203         }
2204 }
2205
2206 static void
2207 ev_window_load_print_settings_from_metadata (EvWindow *window)
2208 {
2209         gchar *uri = window->priv->uri;
2210         gint   i;
2211         
2212         /* Load print setting that are specific to the document */
2213         for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) {
2214                 GValue   value = { 0, };
2215                 gboolean success;
2216
2217                 success = ev_metadata_manager_get (uri, document_print_settings[i], &value, TRUE);
2218                 gtk_print_settings_set (window->priv->print_settings,
2219                                         document_print_settings[i],
2220                                         success ? g_value_get_string (&value) : NULL);
2221         }
2222 }
2223
2224 static void
2225 ev_window_save_print_settings (EvWindow *window)
2226 {
2227         gchar *uri = window->priv->uri;
2228         gint   i;
2229         
2230         /* Save print settings that are specific to the document */
2231         for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) {
2232                 const gchar *value;
2233
2234                 value = gtk_print_settings_get (window->priv->print_settings,
2235                                                 document_print_settings[i]);
2236                 ev_metadata_manager_set_string (uri, document_print_settings[i], value);
2237         }
2238 }
2239
2240 static void
2241 ev_window_print_finished (GtkPrintJob *print_job,
2242                           EvWindow    *window,
2243                           GError      *error)
2244 {
2245         ev_window_clear_print_job (window);
2246         
2247         if (error) {
2248                 GtkWidget *dialog;
2249                 
2250                 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
2251                                                  GTK_DIALOG_MODAL,
2252                                                  GTK_MESSAGE_ERROR,
2253                                                  GTK_BUTTONS_OK,
2254                                                  _("Failed to print document"));
2255                 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
2256                                                           "%s", error->message);
2257
2258                 gtk_dialog_run (GTK_DIALOG (dialog));
2259                 gtk_widget_destroy (dialog);
2260         } else {
2261                 /* If printed successfully, save print settings */
2262                 ev_application_set_print_settings (EV_APP,
2263                                                    window->priv->print_settings);
2264                 ev_window_save_print_settings (window);
2265         }
2266 }
2267
2268 static void
2269 ev_window_print_send (EvWindow    *window,
2270                       const gchar *filename)
2271 {
2272         GtkPrintSettings *settings;
2273         EvFileExporterCapabilities capabilities;
2274         
2275         /* Some printers take into account some print settings,
2276          * and others don't. However we have exported the document
2277          * to a ps or pdf file according to such print settings. So,
2278          * we want to send the exported file to printer with those
2279          * settings set to default values. 
2280          */
2281         settings = gtk_print_settings_copy (window->priv->print_settings);
2282         capabilities = ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (window->priv->document));
2283
2284         gtk_print_settings_set_page_ranges (settings, NULL, 0);
2285         gtk_print_settings_set_print_pages (settings, GTK_PRINT_PAGES_ALL);
2286         if (capabilities & EV_FILE_EXPORTER_CAN_COPIES)
2287                 gtk_print_settings_set_n_copies (settings, 1);
2288         if (capabilities & EV_FILE_EXPORTER_CAN_PAGE_SET)
2289                 gtk_print_settings_set_page_set (settings, GTK_PAGE_SET_ALL);
2290         if (capabilities & EV_FILE_EXPORTER_CAN_SCALE)
2291                 gtk_print_settings_set_scale (settings, 1.0);
2292         if (capabilities & EV_FILE_EXPORTER_CAN_COLLATE)
2293                 gtk_print_settings_set_collate (settings, FALSE);
2294         if (capabilities & EV_FILE_EXPORTER_CAN_REVERSE)
2295                 gtk_print_settings_set_reverse (settings, FALSE);
2296         if (capabilities & EV_FILE_EXPORTER_CAN_NUMBER_UP) {
2297                 gtk_print_settings_set_number_up (settings, 1);
2298                 gtk_print_settings_set_int (settings, "cups-"GTK_PRINT_SETTINGS_NUMBER_UP, 1);
2299         }
2300         
2301         if (window->priv->print_preview) {
2302                 gchar *uri;
2303                 gchar *print_settings_file = NULL;
2304
2305                 ev_application_set_print_settings (EV_APP,
2306                                                    window->priv->print_settings);
2307                 
2308 #if GTK_CHECK_VERSION (2, 11, 0)
2309                 print_settings_file = ev_tmp_filename ("print-settings");
2310                 gtk_print_settings_to_file (settings, print_settings_file, NULL);
2311 #endif
2312                 uri = g_filename_to_uri (filename, NULL, NULL);
2313                 ev_application_open_uri_at_dest (EV_APP,
2314                                                  uri, 
2315                                                  gtk_window_get_screen (GTK_WINDOW (window)),
2316                                                  NULL,
2317                                                  EV_WINDOW_MODE_PREVIEW,
2318                                                  NULL, 
2319                                                  TRUE,
2320                                                  print_settings_file,
2321                                                  GDK_CURRENT_TIME);
2322                 g_free (print_settings_file);
2323                 g_free (uri);
2324         } else {
2325                 GtkPrintJob *job;
2326                 GError      *error = NULL;
2327         
2328                 job = gtk_print_job_new (gtk_window_get_title (GTK_WINDOW (window)),
2329                                          window->priv->printer,
2330                                          settings,
2331                                          window->priv->print_page_setup);
2332
2333                 if (window->priv->gtk_print_job)
2334                         g_object_unref (window->priv->gtk_print_job);
2335                 window->priv->gtk_print_job = job;
2336
2337                 if (gtk_print_job_set_source_file (job, filename, &error)) {
2338                         gtk_print_job_send (job,
2339                                             (GtkPrintJobCompleteFunc)ev_window_print_finished,
2340                                             window, NULL);
2341                 } else {
2342                         ev_window_clear_print_job (window);
2343                         g_warning ("%s", error->message);
2344                         g_error_free (error);
2345                 }
2346         }
2347
2348         g_object_unref (settings);
2349 }
2350
2351 static void
2352 ev_window_print_job_cb (EvJobPrint *job,
2353                         EvWindow   *window)
2354 {
2355         if (job->error) {
2356                 g_warning ("%s", job->error->message);
2357                 ev_window_clear_print_job (window);
2358                 return;
2359         }
2360
2361         g_assert (job->temp_file != NULL);
2362
2363         ev_window_print_send (window, job->temp_file);
2364 }
2365
2366 static gboolean
2367 ev_window_print_dialog_response_cb (GtkDialog *dialog,
2368                                     gint       response,
2369                                     EvWindow  *window)
2370 {
2371         EvPrintRange  *ranges = NULL;
2372         EvPrintPageSet page_set;
2373         gint           n_ranges = 0;
2374         gint           copies;
2375         gint           pages_per_sheet;
2376         gboolean       collate;
2377         gboolean       reverse;
2378         gdouble        scale;
2379         gint           current_page;
2380         gdouble        width;
2381         gdouble        height;
2382         GtkPrintPages  print_pages;
2383         const gchar   *file_format;
2384         
2385         if (response != GTK_RESPONSE_OK &&
2386             response != GTK_RESPONSE_APPLY) {
2387                 gtk_widget_destroy (GTK_WIDGET (dialog));
2388                 window->priv->print_dialog = NULL;
2389
2390                 return FALSE;
2391         }
2392
2393         window->priv->print_preview = (response == GTK_RESPONSE_APPLY);
2394
2395         if (window->priv->printer)
2396                 g_object_unref (window->priv->printer);
2397         if (window->priv->print_settings)
2398                 g_object_unref (window->priv->print_settings);
2399         if (window->priv->print_page_setup)
2400                 g_object_unref (window->priv->print_page_setup);
2401         
2402         window->priv->printer = g_object_ref (
2403                 gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (dialog)));
2404         window->priv->print_settings = g_object_ref (
2405                 gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dialog)));
2406         window->priv->print_page_setup = g_object_ref (
2407                 gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (dialog)));
2408
2409         file_format = gtk_print_settings_get (window->priv->print_settings,
2410                                               GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
2411         
2412         if (!gtk_printer_accepts_ps (window->priv->printer)) {
2413                 GtkWidget *msgdialog;
2414
2415                 msgdialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
2416                                                     GTK_DIALOG_MODAL,
2417                                                     GTK_MESSAGE_ERROR,
2418                                                     GTK_BUTTONS_OK,
2419                                                     _("Printing is not supported on this printer."));
2420                 
2421                 gtk_dialog_run (GTK_DIALOG (msgdialog));
2422                 gtk_widget_destroy (msgdialog);
2423
2424                 return FALSE;
2425         }
2426
2427         ev_window_clear_print_job (window);
2428         
2429         current_page = gtk_print_unix_dialog_get_current_page (GTK_PRINT_UNIX_DIALOG (dialog));
2430         print_pages = gtk_print_settings_get_print_pages (window->priv->print_settings);
2431         
2432         switch (print_pages) {
2433         case GTK_PRINT_PAGES_CURRENT:
2434                 ranges = g_new0 (EvPrintRange, 1);
2435                 
2436                 ranges->start = current_page;
2437                 ranges->end = current_page;
2438                 n_ranges = 1;
2439                                 
2440                 break;
2441         case GTK_PRINT_PAGES_RANGES: {
2442                 GtkPageRange *page_range;
2443                 
2444                 page_range = gtk_print_settings_get_page_ranges (window->priv->print_settings,
2445                                                                  &n_ranges);
2446                 if (n_ranges > 0)
2447                         ranges = g_memdup (page_range, n_ranges * sizeof (GtkPageRange));
2448         }
2449                 break;
2450         case GTK_PRINT_PAGES_ALL: {
2451                 gint n_pages;
2452
2453                 n_pages = ev_page_cache_get_n_pages (ev_page_cache_get (window->priv->document));
2454                 
2455                 ranges = g_new0 (EvPrintRange, 1);
2456
2457                 ranges->start = 0;
2458                 ranges->end = n_pages - 1;
2459                 n_ranges = 1;
2460         }
2461                 break;
2462         }
2463
2464         page_set = (EvPrintPageSet)gtk_print_settings_get_page_set (window->priv->print_settings);
2465
2466         scale = gtk_print_settings_get_scale (window->priv->print_settings) * 0.01;
2467         
2468         width = gtk_page_setup_get_paper_width (window->priv->print_page_setup,
2469                                                 GTK_UNIT_POINTS);
2470         height = gtk_page_setup_get_paper_height (window->priv->print_page_setup,
2471                                                   GTK_UNIT_POINTS);
2472         
2473         if (scale != 1.0) {
2474                 width *= scale;
2475                 height *= scale;
2476         }
2477
2478         pages_per_sheet = gtk_print_settings_get_number_up (window->priv->print_settings);
2479         
2480         copies = gtk_print_settings_get_n_copies (window->priv->print_settings);
2481         collate = gtk_print_settings_get_collate (window->priv->print_settings);
2482         reverse = gtk_print_settings_get_reverse (window->priv->print_settings);
2483         
2484         window->priv->print_job = ev_job_print_new (window->priv->document,
2485                                                     file_format ? file_format : "ps",
2486                                                     width, height,
2487                                                     ranges, n_ranges,
2488                                                     page_set,
2489                                                     pages_per_sheet,
2490                                                     copies, collate,
2491                                                     reverse);
2492         
2493         g_signal_connect (window->priv->print_job, "finished",
2494                           G_CALLBACK (ev_window_print_job_cb),
2495                           window);
2496         /* The priority doesn't matter for this job */
2497         ev_job_queue_add_job (window->priv->print_job, EV_JOB_PRIORITY_LOW);
2498         
2499         gtk_widget_destroy (GTK_WIDGET (dialog));
2500         window->priv->print_dialog = NULL;
2501
2502         return TRUE;
2503 }
2504
2505 void
2506 ev_window_print_range (EvWindow *ev_window, int first_page, int last_page)
2507 {
2508         GtkWidget           *dialog;
2509         EvPageCache         *page_cache;
2510         gint                 current_page;
2511         gint                 document_last_page;
2512         GtkPrintCapabilities capabilities;
2513
2514         g_return_if_fail (EV_IS_WINDOW (ev_window));
2515         g_return_if_fail (ev_window->priv->document != NULL);
2516
2517         if (ev_window->priv->print_dialog) {
2518                 gtk_window_present (GTK_WINDOW (ev_window->priv->print_dialog));
2519                 return;
2520         }
2521         
2522         page_cache = ev_page_cache_get (ev_window->priv->document);
2523         current_page = ev_page_cache_get_current_page (page_cache);
2524         document_last_page = ev_page_cache_get_n_pages (page_cache);
2525
2526         if (!ev_window->priv->print_settings) {
2527                 ev_window->priv->print_settings = gtk_print_settings_copy (
2528                         ev_application_get_print_settings (EV_APP));
2529                 ev_window_load_print_settings_from_metadata (ev_window);
2530         }
2531
2532         if (first_page != 1 || last_page != document_last_page) {
2533                 GtkPageRange range;
2534
2535                 /* Ranges in GtkPrint are 0 - N */
2536                 range.start = first_page - 1;
2537                 range.end = last_page - 1;
2538                 
2539                 gtk_print_settings_set_print_pages (ev_window->priv->print_settings,
2540                                                     GTK_PRINT_PAGES_RANGES);
2541                 gtk_print_settings_set_page_ranges (ev_window->priv->print_settings,
2542                                                     &range, 1);
2543         }
2544
2545         dialog = gtk_print_unix_dialog_new (_("Print"), GTK_WINDOW (ev_window));
2546         ev_window->priv->print_dialog = dialog;
2547         
2548         capabilities = GTK_PRINT_CAPABILITY_PREVIEW |
2549                 ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (ev_window->priv->document));
2550         gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dialog),
2551                                                        capabilities);
2552
2553         gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (dialog),
2554                                                 current_page);
2555         
2556         gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (dialog),
2557                                             ev_window->priv->print_settings);
2558         
2559         if (ev_window->priv->print_page_setup)
2560                 gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (dialog),
2561                                                       ev_window->priv->print_page_setup);
2562         
2563         g_signal_connect (G_OBJECT (dialog), "response",
2564                           G_CALLBACK (ev_window_print_dialog_response_cb),
2565                           ev_window);
2566
2567         gtk_widget_show (dialog);
2568 }
2569
2570 static void
2571 ev_window_print (EvWindow *window)
2572 {
2573         EvPageCache *page_cache;
2574         gint         last_page;
2575
2576         page_cache = ev_page_cache_get (window->priv->document);
2577         last_page = ev_page_cache_get_n_pages (page_cache);
2578
2579         ev_window_print_range (window, 1, last_page);
2580 }
2581
2582 static void
2583 ev_window_cmd_file_print (GtkAction *action, EvWindow *ev_window)
2584 {
2585         ev_window_print (ev_window);
2586 }
2587
2588 static void
2589 ev_window_cmd_file_properties (GtkAction *action, EvWindow *ev_window)
2590 {
2591         if (ev_window->priv->properties == NULL) {
2592                 ev_window->priv->properties = ev_properties_dialog_new ();
2593                 ev_properties_dialog_set_document (EV_PROPERTIES_DIALOG (ev_window->priv->properties),
2594                                                    ev_window->priv->document);
2595                 g_object_add_weak_pointer (G_OBJECT (ev_window->priv->properties),
2596                                            (gpointer) &(ev_window->priv->properties));
2597                 gtk_window_set_transient_for (GTK_WINDOW (ev_window->priv->properties),
2598                                               GTK_WINDOW (ev_window));
2599         }
2600
2601         ev_document_fc_mutex_lock ();
2602         gtk_widget_show (ev_window->priv->properties);
2603         ev_document_fc_mutex_unlock ();
2604 }
2605                                         
2606 static void
2607 ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window)
2608 {
2609         g_return_if_fail (EV_IS_WINDOW (ev_window));
2610
2611         gtk_widget_destroy (GTK_WIDGET (ev_window));
2612 }
2613
2614 static void
2615 ev_window_cmd_focus_page_selector (GtkAction *act, EvWindow *window)
2616 {
2617         GtkAction *action;
2618         
2619         update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, TRUE);
2620         ev_window_set_action_sensitive (window, "ViewToolbar", FALSE);
2621         update_chrome_visibility (window);
2622         
2623         action = gtk_action_group_get_action (window->priv->action_group,
2624                                               PAGE_SELECTOR_ACTION);
2625         ev_page_action_grab_focus (EV_PAGE_ACTION (action));
2626 }
2627
2628 static void
2629 ev_window_cmd_scroll_forward (GtkAction *action, EvWindow *window)
2630 {
2631         ev_view_scroll (EV_VIEW (window->priv->view), EV_SCROLL_PAGE_FORWARD, FALSE);
2632 }
2633
2634 static void
2635 ev_window_cmd_scroll_backward (GtkAction *action, EvWindow *window)
2636 {
2637         ev_view_scroll (EV_VIEW (window->priv->view), EV_SCROLL_PAGE_BACKWARD, FALSE);
2638 }
2639
2640 static void
2641 ev_window_cmd_continuous (GtkAction *action, EvWindow *ev_window)
2642 {
2643         gboolean continuous;
2644
2645         ev_window_stop_presentation (ev_window, TRUE);
2646         continuous = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
2647         g_object_set (G_OBJECT (ev_window->priv->view),
2648                       "continuous", continuous,
2649                       NULL);
2650         ev_window_update_actions (ev_window);
2651 }
2652
2653 static void
2654 ev_window_cmd_dual (GtkAction *action, EvWindow *ev_window)
2655 {
2656         gboolean dual_page;
2657
2658         ev_window_stop_presentation (ev_window, TRUE);
2659         dual_page = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
2660         g_object_set (G_OBJECT (ev_window->priv->view),
2661                       "dual-page", dual_page,
2662                       NULL);
2663         ev_window_update_actions (ev_window);
2664 }
2665
2666 static void
2667 ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window)
2668 {
2669         ev_window_stop_presentation (ev_window, TRUE);
2670
2671         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2672                 ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_BEST_FIT);
2673         } else {
2674                 ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE);
2675         }
2676         ev_window_update_actions (ev_window);
2677 }
2678
2679 static void
2680 ev_window_cmd_view_page_width (GtkAction *action, EvWindow *ev_window)
2681 {
2682         ev_window_stop_presentation (ev_window, TRUE);
2683
2684         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2685                 ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FIT_WIDTH);
2686         } else {
2687                 ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE);
2688         }
2689         ev_window_update_actions (ev_window);
2690 }
2691
2692
2693 static void
2694 ev_window_cmd_edit_select_all (GtkAction *action, EvWindow *ev_window)
2695 {
2696         g_return_if_fail (EV_IS_WINDOW (ev_window));
2697
2698         ev_view_select_all (EV_VIEW (ev_window->priv->view));
2699 }
2700
2701 static void
2702 ev_window_cmd_edit_find (GtkAction *action, EvWindow *ev_window)
2703 {
2704         g_return_if_fail (EV_IS_WINDOW (ev_window));
2705
2706         if (ev_window->priv->document == NULL || !EV_IS_DOCUMENT_FIND (ev_window->priv->document)) {
2707                 g_error ("Find action should be insensitive since document doesn't support find");
2708                 return;
2709         } 
2710
2711         update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE);
2712         update_chrome_visibility (ev_window);
2713         gtk_widget_grab_focus (ev_window->priv->find_bar);
2714 }
2715
2716 static void
2717 ev_window_cmd_edit_find_next (GtkAction *action, EvWindow *ev_window)
2718 {
2719         g_return_if_fail (EV_IS_WINDOW (ev_window));
2720
2721         update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE);
2722         update_chrome_visibility (ev_window);
2723         gtk_widget_grab_focus (ev_window->priv->find_bar);
2724         ev_view_find_next (EV_VIEW (ev_window->priv->view));
2725 }
2726
2727 static void
2728 ev_window_cmd_edit_find_previous (GtkAction *action, EvWindow *ev_window)
2729 {
2730         g_return_if_fail (EV_IS_WINDOW (ev_window));
2731
2732         update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE);
2733         update_chrome_visibility (ev_window);
2734         gtk_widget_grab_focus (ev_window->priv->find_bar);
2735         ev_view_find_previous (EV_VIEW (ev_window->priv->view));
2736 }
2737
2738 static void
2739 ev_window_cmd_edit_copy (GtkAction *action, EvWindow *ev_window)
2740 {
2741         g_return_if_fail (EV_IS_WINDOW (ev_window));
2742
2743         ev_view_copy (EV_VIEW (ev_window->priv->view));
2744 }
2745
2746 static void
2747 ev_window_sidebar_position_change_cb (GObject *object, GParamSpec *pspec,
2748                                       EvWindow *ev_window)
2749 {
2750         if (!ev_window_is_empty (ev_window))
2751                 ev_metadata_manager_set_int (ev_window->priv->uri, "sidebar_size",
2752                                              gtk_paned_get_position (GTK_PANED (object)));
2753 }
2754
2755 static void
2756 ev_window_update_fullscreen_action (EvWindow *window)
2757 {
2758         GtkAction *action;
2759
2760         action = gtk_action_group_get_action (window->priv->action_group, "ViewFullscreen");
2761         g_signal_handlers_block_by_func
2762                 (action, G_CALLBACK (ev_window_cmd_view_fullscreen), window);
2763         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
2764                                       ev_view_get_fullscreen (EV_VIEW (window->priv->view)));
2765         g_signal_handlers_unblock_by_func
2766                 (action, G_CALLBACK (ev_window_cmd_view_fullscreen), window);
2767 }
2768
2769 static void
2770 fullscreen_toolbar_setup_item_properties (GtkUIManager *ui_manager)
2771 {
2772         GtkWidget *item;
2773
2774         item = gtk_ui_manager_get_widget (ui_manager, "/FullscreenToolbar/GoPreviousPage");
2775         g_object_set (item, "is-important", FALSE, NULL);
2776
2777         item = gtk_ui_manager_get_widget (ui_manager, "/FullscreenToolbar/GoNextPage");
2778         g_object_set (item, "is-important", FALSE, NULL);
2779
2780         item = gtk_ui_manager_get_widget (ui_manager, "/FullscreenToolbar/StartPresentation");
2781         g_object_set (item, "is-important", TRUE, NULL);
2782         
2783         item = gtk_ui_manager_get_widget (ui_manager, "/FullscreenToolbar/LeaveFullscreen");
2784         g_object_set (item, "is-important", TRUE, NULL);
2785 }
2786
2787 static void
2788 fullscreen_toolbar_remove_shadow (GtkWidget *toolbar)
2789 {
2790         static gboolean done = FALSE;
2791
2792         if (!done) {
2793                 gtk_rc_parse_string (
2794                         "\n"
2795                         "   style \"fullscreen-toolbar-style\"\n"
2796                         "   {\n"
2797                         "      GtkToolbar::shadow-type=GTK_SHADOW_NONE\n"
2798                         "   }\n"
2799                         "\n"
2800                         "    widget \"*.fullscreen-toolbar\" style \"fullscreen-toolbar-style\"\n"
2801                         "\n");
2802                 done = TRUE;
2803         }
2804         
2805         gtk_widget_set_name (toolbar, "fullscreen-toolbar");
2806 }
2807
2808 static void
2809 ev_window_run_fullscreen (EvWindow *window)
2810 {
2811         EvView  *view = EV_VIEW (window->priv->view);
2812         gboolean fullscreen_window = TRUE;
2813
2814         if (ev_view_get_fullscreen (view))
2815                 return;
2816         
2817         if (!window->priv->fullscreen_toolbar) {
2818                 window->priv->fullscreen_toolbar =
2819                         gtk_ui_manager_get_widget (window->priv->ui_manager,
2820                                                    "/FullscreenToolbar");
2821
2822                 gtk_toolbar_set_style (GTK_TOOLBAR (window->priv->fullscreen_toolbar),
2823                                        GTK_TOOLBAR_BOTH_HORIZ);
2824                 fullscreen_toolbar_remove_shadow (window->priv->fullscreen_toolbar);
2825                 fullscreen_toolbar_setup_item_properties (window->priv->ui_manager);
2826
2827                 gtk_box_pack_start (GTK_BOX (window->priv->main_box),
2828                                     window->priv->fullscreen_toolbar,
2829                                     FALSE, FALSE, 0);
2830                 gtk_box_reorder_child (GTK_BOX (window->priv->main_box),
2831                                        window->priv->fullscreen_toolbar, 1);
2832         }
2833
2834         if (ev_view_get_presentation (view)) {
2835                 ev_window_stop_presentation (window, FALSE);
2836                 fullscreen_window = FALSE;
2837         }
2838
2839         g_object_set (G_OBJECT (window->priv->scrolled_window),
2840                       "shadow-type", GTK_SHADOW_NONE,
2841                       NULL);
2842
2843         ev_view_set_fullscreen (view, TRUE);
2844         ev_window_update_fullscreen_action (window);
2845
2846         /* If the user doesn't have the main toolbar he/she won't probably want
2847          * the toolbar in fullscreen mode. See bug #483048
2848          */
2849         update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR,
2850                             (window->priv->chrome & EV_CHROME_TOOLBAR) != 0);
2851         update_chrome_visibility (window);
2852
2853         if (fullscreen_window)
2854                 gtk_window_fullscreen (GTK_WINDOW (window));
2855         gtk_widget_grab_focus (window->priv->view);
2856
2857         if (!ev_window_is_empty (window))
2858                 ev_metadata_manager_set_boolean (window->priv->uri, "fullscreen", TRUE);
2859 }
2860
2861 static void
2862 ev_window_stop_fullscreen (EvWindow *window,
2863                            gboolean  unfullscreen_window)
2864 {
2865         EvView *view = EV_VIEW (window->priv->view);
2866
2867         if (!ev_view_get_fullscreen (view))
2868                 return;
2869
2870         g_object_set (G_OBJECT (window->priv->scrolled_window),
2871                       "shadow-type", GTK_SHADOW_IN,
2872                       NULL);
2873
2874         ev_view_set_fullscreen (view, FALSE);
2875         ev_window_update_fullscreen_action (window);
2876         update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR, FALSE);
2877         update_chrome_visibility (window);
2878         if (unfullscreen_window)
2879                 gtk_window_unfullscreen (GTK_WINDOW (window));
2880
2881         if (!ev_window_is_empty (window))
2882                 ev_metadata_manager_set_boolean (window->priv->uri, "fullscreen", FALSE);
2883 }
2884
2885 static void
2886 ev_window_cmd_view_fullscreen (GtkAction *action, EvWindow *window)
2887 {
2888         gboolean fullscreen;
2889
2890         fullscreen = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
2891         if (fullscreen) {
2892                 ev_window_run_fullscreen (window);
2893         } else {
2894                 ev_window_stop_fullscreen (window, TRUE);
2895         }
2896 }
2897
2898 static gboolean
2899 presentation_timeout_cb (EvWindow *window)
2900 {
2901         EvView *view = EV_VIEW (window->priv->view);
2902
2903         if (!view || !ev_view_get_presentation (EV_VIEW (view)))
2904                 return FALSE;
2905
2906         ev_view_hide_cursor (EV_VIEW (window->priv->view));
2907         window->priv->presentation_timeout_id = 0;
2908
2909         return FALSE;
2910 }
2911
2912 static void
2913 presentation_set_timeout (EvWindow *window)
2914 {
2915         if (window->priv->presentation_timeout_id > 0) {
2916                 g_source_remove (window->priv->presentation_timeout_id);
2917         }
2918
2919         window->priv->presentation_timeout_id =
2920                 g_timeout_add_seconds (PRESENTATION_TIMEOUT,
2921                                        (GSourceFunc)presentation_timeout_cb, window);
2922
2923         ev_view_show_cursor (EV_VIEW (window->priv->view));
2924 }
2925
2926 static void
2927 presentation_clear_timeout (EvWindow *window)
2928 {
2929         if (window->priv->presentation_timeout_id > 0) {
2930                 g_source_remove (window->priv->presentation_timeout_id);
2931         }
2932         
2933         window->priv->presentation_timeout_id = 0;
2934
2935         ev_view_show_cursor (EV_VIEW (window->priv->view));
2936 }
2937
2938 static gboolean
2939 presentation_motion_notify_cb (GtkWidget *widget,
2940                                GdkEventMotion *event,
2941                                gpointer user_data)
2942 {
2943         EvWindow *window = EV_WINDOW (user_data);
2944
2945         presentation_set_timeout (window);
2946
2947         return FALSE;
2948 }
2949
2950 static gboolean
2951 presentation_leave_notify_cb (GtkWidget *widget,
2952                               GdkEventCrossing *event,
2953                               gpointer user_data)
2954 {
2955         EvWindow *window = EV_WINDOW (user_data);
2956
2957         presentation_clear_timeout (window);
2958
2959         return FALSE;
2960 }
2961
2962 static void
2963 ev_window_update_presentation_action (EvWindow *window)
2964 {
2965         GtkAction *action;
2966
2967         action = gtk_action_group_get_action (window->priv->action_group, "ViewPresentation");
2968         g_signal_handlers_block_by_func
2969                 (action, G_CALLBACK (ev_window_cmd_view_presentation), window);
2970         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
2971                                       ev_view_get_presentation (EV_VIEW (window->priv->view)));
2972         g_signal_handlers_unblock_by_func
2973                 (action, G_CALLBACK (ev_window_cmd_view_presentation), window);
2974 }
2975
2976 static void
2977 ev_window_run_presentation (EvWindow *window)
2978 {
2979         EvView  *view = EV_VIEW (window->priv->view);
2980         gboolean fullscreen_window = TRUE;
2981
2982         if (ev_view_get_presentation (view))
2983                 return;
2984
2985         if (ev_view_get_fullscreen (view)) {
2986                 ev_window_stop_fullscreen (window, FALSE);
2987                 fullscreen_window = FALSE;
2988         }
2989         
2990         g_object_set (G_OBJECT (window->priv->scrolled_window),
2991                       "shadow-type", GTK_SHADOW_NONE,
2992                       NULL);
2993
2994         ev_view_set_presentation (view, TRUE);
2995         ev_window_update_presentation_action (window);
2996
2997         update_chrome_visibility (window);
2998         
2999         gtk_widget_grab_focus (window->priv->view);
3000         if (fullscreen_window)
3001                 gtk_window_fullscreen (GTK_WINDOW (window));
3002
3003         g_signal_connect (window->priv->view,
3004                           "motion-notify-event",
3005                           G_CALLBACK (presentation_motion_notify_cb),
3006                           window);
3007         g_signal_connect (window->priv->view,
3008                           "leave-notify-event",
3009                           G_CALLBACK (presentation_leave_notify_cb),
3010                           window);
3011         presentation_set_timeout (window);
3012
3013         ev_application_screensaver_disable (EV_APP);
3014         
3015         if (!ev_window_is_empty (window))
3016                 ev_metadata_manager_set_boolean (window->priv->uri, "presentation", TRUE);
3017 }
3018
3019 static void
3020 ev_window_stop_presentation (EvWindow *window,
3021                              gboolean  unfullscreen_window)
3022 {
3023         EvView *view = EV_VIEW (window->priv->view);
3024         
3025         if (!ev_view_get_presentation (view))
3026                 return;
3027
3028         g_object_set (G_OBJECT (window->priv->scrolled_window),
3029                       "shadow-type", GTK_SHADOW_IN,
3030                       NULL);
3031
3032         ev_view_set_presentation (EV_VIEW (window->priv->view), FALSE);
3033         ev_window_update_presentation_action (window);
3034         update_chrome_visibility (window);
3035         if (unfullscreen_window)
3036                 gtk_window_unfullscreen (GTK_WINDOW (window));
3037
3038         g_signal_handlers_disconnect_by_func (window->priv->view,
3039                                               (gpointer) presentation_motion_notify_cb,
3040                                               window);
3041         g_signal_handlers_disconnect_by_func (window->priv->view,
3042                                               (gpointer) presentation_leave_notify_cb,
3043                                               window);
3044         presentation_clear_timeout (window);
3045
3046         ev_application_screensaver_enable (EV_APP);
3047
3048         if (!ev_window_is_empty (window))
3049                 ev_metadata_manager_set_boolean (window->priv->uri, "presentation", FALSE);
3050 }
3051
3052 static void
3053 ev_window_cmd_view_presentation (GtkAction *action, EvWindow *window)
3054 {
3055         gboolean presentation;
3056
3057         presentation = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
3058         if (presentation) {
3059                 ev_window_run_presentation (window);
3060         } else {
3061                 ev_window_stop_presentation (window, TRUE);
3062         }
3063 }
3064
3065 static void
3066 ev_window_run_preview (EvWindow *window)
3067 {
3068         GtkAction *action;
3069         
3070         if (!window->priv->preview_toolbar) {
3071                 window->priv->preview_toolbar =
3072                         gtk_ui_manager_get_widget (window->priv->ui_manager,
3073                                                    "/PreviewToolbar");
3074
3075                 gtk_box_pack_start (GTK_BOX (window->priv->main_box),
3076                                     window->priv->preview_toolbar,
3077                                     FALSE, FALSE, 0);
3078                 gtk_box_reorder_child (GTK_BOX (window->priv->main_box),
3079                                        window->priv->preview_toolbar, 1);
3080         }
3081         
3082         ev_view_set_continuous (EV_VIEW (window->priv->view), FALSE); 
3083         
3084         update_chrome_flag (window, EV_CHROME_TOOLBAR, FALSE);
3085         update_chrome_flag (window, EV_CHROME_MENUBAR, FALSE);
3086         update_chrome_flag (window, EV_CHROME_SIDEBAR, FALSE);
3087
3088         update_chrome_flag (window, EV_CHROME_PREVIEW_TOOLBAR, TRUE);
3089         
3090         action = gtk_action_group_get_action (window->priv->action_group,
3091                                               "PreviewPrint");
3092 #if GTK_CHECK_VERSION (2, 11, 0)
3093         gtk_action_set_visible (action, TRUE);
3094 #else
3095         gtk_action_set_visible (action, FALSE);
3096 #endif
3097
3098         update_chrome_visibility (window);
3099 }
3100
3101 static void
3102 ev_window_screen_changed (GtkWidget *widget,
3103                           GdkScreen *old_screen)
3104 {
3105         EvWindow *window = EV_WINDOW (widget);
3106         EvWindowPrivate *priv = window->priv;
3107         GdkScreen *screen;
3108
3109         screen = gtk_widget_get_screen (widget);
3110         if (screen == old_screen)
3111                 return;
3112
3113         ev_view_set_screen_dpi (EV_VIEW (priv->view),
3114                                 get_screen_dpi (GTK_WINDOW (window)));
3115         
3116         if (GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed) {
3117                 GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed (widget, old_screen);
3118         }
3119 }
3120
3121 static void
3122 ev_window_set_page_mode (EvWindow         *window,
3123                          EvWindowPageMode  page_mode)
3124 {
3125         GtkWidget *child = NULL;
3126         GtkWidget *real_child;
3127
3128         if (window->priv->page_mode == page_mode)
3129                 return;
3130
3131         window->priv->page_mode = page_mode;
3132
3133         switch (page_mode) {
3134                 case PAGE_MODE_DOCUMENT:
3135                         child = window->priv->view;
3136                         break;
3137                 case PAGE_MODE_PASSWORD:
3138                         child = window->priv->password_view;
3139                         break;
3140                 default:
3141                         g_assert_not_reached ();
3142         }
3143
3144         real_child = gtk_bin_get_child (GTK_BIN (window->priv->scrolled_window));
3145         if (child != real_child) {
3146                 gtk_container_remove (GTK_CONTAINER (window->priv->scrolled_window),
3147                                       real_child);
3148                 gtk_container_add (GTK_CONTAINER (window->priv->scrolled_window),
3149                                    child);
3150         }
3151         ev_window_update_actions (window);
3152 }
3153
3154
3155 static void
3156 ev_window_cmd_edit_rotate_left (GtkAction *action, EvWindow *ev_window)
3157 {
3158         ev_view_rotate_left (EV_VIEW (ev_window->priv->view));
3159 }
3160
3161 static void
3162 ev_window_cmd_edit_rotate_right (GtkAction *action, EvWindow *ev_window)
3163 {
3164         ev_view_rotate_right (EV_VIEW (ev_window->priv->view));
3165 }
3166
3167 static void
3168 ev_window_cmd_edit_toolbar_cb (GtkDialog *dialog, gint response, gpointer data)
3169 {
3170         EvWindow *ev_window = EV_WINDOW (data);
3171         egg_editable_toolbar_set_edit_mode
3172                         (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), FALSE);
3173         ev_application_save_toolbars_model (EV_APP);
3174         gtk_widget_destroy (GTK_WIDGET (dialog));
3175 }
3176
3177 static void
3178 ev_window_cmd_edit_toolbar (GtkAction *action, EvWindow *ev_window)
3179 {
3180         GtkWidget *dialog;
3181         GtkWidget *editor;
3182
3183         dialog = gtk_dialog_new_with_buttons (_("Toolbar Editor"),
3184                                               GTK_WINDOW (ev_window), 
3185                                               GTK_DIALOG_DESTROY_WITH_PARENT, 
3186                                               GTK_STOCK_CLOSE,
3187                                               GTK_RESPONSE_CLOSE, 
3188                                               NULL);
3189         gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
3190         gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)), 5);
3191         gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
3192         gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
3193         gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400);
3194           
3195         editor = egg_toolbar_editor_new (ev_window->priv->ui_manager,
3196                                          ev_application_get_toolbars_model (EV_APP));
3197         gtk_container_set_border_width (GTK_CONTAINER (editor), 5);
3198         gtk_box_set_spacing (GTK_BOX (EGG_TOOLBAR_EDITOR (editor)), 5);
3199              
3200         gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), editor);
3201
3202         egg_editable_toolbar_set_edit_mode
3203                 (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), TRUE);
3204
3205         g_signal_connect (dialog, "response",
3206                           G_CALLBACK (ev_window_cmd_edit_toolbar_cb),
3207                           ev_window);
3208         gtk_widget_show_all (dialog);
3209 }
3210
3211 static void
3212 ev_window_cmd_view_zoom_in (GtkAction *action, EvWindow *ev_window)
3213 {
3214         g_return_if_fail (EV_IS_WINDOW (ev_window));
3215
3216         ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE);
3217         ev_view_zoom_in (EV_VIEW (ev_window->priv->view));
3218 }
3219
3220 static void
3221 ev_window_cmd_view_zoom_out (GtkAction *action, EvWindow *ev_window)
3222 {
3223         g_return_if_fail (EV_IS_WINDOW (ev_window));
3224
3225         ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE);
3226         ev_view_zoom_out (EV_VIEW (ev_window->priv->view));
3227 }
3228
3229 static void
3230 ev_window_cmd_go_previous_page (GtkAction *action, EvWindow *ev_window)
3231 {
3232         g_return_if_fail (EV_IS_WINDOW (ev_window));
3233
3234         ev_view_previous_page (EV_VIEW (ev_window->priv->view));
3235 }
3236
3237 void
3238 ev_window_go_previous_page (EvWindow *ev_window)
3239 {
3240         ev_window_cmd_go_previous_page (NULL, ev_window);
3241 }
3242
3243 static void
3244 ev_window_cmd_go_next_page (GtkAction *action, EvWindow *ev_window)
3245 {
3246         g_return_if_fail (EV_IS_WINDOW (ev_window));
3247
3248         ev_view_next_page (EV_VIEW (ev_window->priv->view));
3249 }
3250
3251 void
3252 ev_window_go_next_page (EvWindow *ev_window)
3253 {
3254         ev_window_cmd_go_next_page (NULL, ev_window);
3255 }
3256
3257 static void
3258 ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window)
3259 {
3260         g_return_if_fail (EV_IS_WINDOW (ev_window));
3261
3262         ev_page_cache_set_current_page (ev_window->priv->page_cache, 0);
3263 }
3264
3265 void
3266 ev_window_go_first_page (EvWindow *ev_window)
3267 {
3268         ev_window_cmd_go_first_page (NULL, ev_window);
3269 }
3270
3271 static void
3272 ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window)
3273 {
3274         int n_pages;
3275
3276         g_return_if_fail (EV_IS_WINDOW (ev_window));
3277
3278         n_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache);
3279         ev_page_cache_set_current_page (ev_window->priv->page_cache, n_pages - 1);
3280 }
3281
3282 void
3283 ev_window_go_last_page (EvWindow *ev_window)
3284 {
3285         ev_window_cmd_go_last_page (NULL, ev_window);
3286 }
3287
3288 static void
3289 ev_window_cmd_go_forward (GtkAction *action, EvWindow *ev_window)
3290 {
3291         int n_pages, current_page;
3292         
3293         g_return_if_fail (EV_IS_WINDOW (ev_window));
3294
3295         n_pages = ev_page_cache_get_n_pages (ev_window->priv->page_cache);
3296         current_page = ev_page_cache_get_current_page (ev_window->priv->page_cache);
3297         
3298         if (current_page + 10 < n_pages)
3299                 ev_page_cache_set_current_page (ev_window->priv->page_cache, current_page + 10);
3300 }
3301
3302 static void
3303 ev_window_cmd_go_backward (GtkAction *action, EvWindow *ev_window)
3304 {
3305         int current_page;
3306         
3307         g_return_if_fail (EV_IS_WINDOW (ev_window));
3308
3309         current_page = ev_page_cache_get_current_page (ev_window->priv->page_cache);
3310         
3311         if (current_page - 10 >= 0)
3312                 ev_page_cache_set_current_page (ev_window->priv->page_cache, current_page - 10);
3313 }
3314
3315 static void
3316 ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window)
3317 {
3318         ev_window_reload_document (ev_window);
3319 }
3320
3321 static void
3322 ev_window_cmd_view_autoscroll (GtkAction *action, EvWindow *ev_window)
3323 {
3324         ev_view_autoscroll_start (EV_VIEW (ev_window->priv->view));
3325 }
3326
3327 static void
3328 ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window)
3329 {
3330         GError *error = NULL;
3331         GdkScreen *screen;
3332         char *command;
3333         const char *lang;
3334         char *uri = NULL;
3335
3336         int i;
3337
3338         const char * const * langs = g_get_language_names ();
3339
3340         for (i = 0; langs[i]; i++) {
3341                 lang = langs[i];
3342                 if (strchr (lang, '.')) {
3343                         continue;
3344                 }
3345
3346                 uri = g_build_filename(GNOMEDATADIR,
3347                                        "/gnome/help/" PACKAGE,
3348                                        lang,
3349                                        "/evince.xml",
3350                                        NULL);
3351                                         
3352                 if (g_file_test (uri, G_FILE_TEST_EXISTS)) {
3353                         break;
3354                 }
3355                 g_free (uri);
3356                 uri = NULL;
3357         }
3358
3359         if (uri == NULL) {
3360                 g_warning ("Cannot find help");
3361                 return;
3362         }
3363         
3364         command = g_strconcat ("gnome-help ghelp://", uri,  NULL);
3365         g_free (uri);
3366         
3367         screen = gtk_widget_get_screen (GTK_WIDGET (ev_window));
3368         gdk_spawn_command_line_on_screen (screen, command, &error);
3369         if (error != NULL) {
3370                 g_warning ("%s", error->message);
3371                 g_error_free (error);
3372         }
3373         g_free (command);
3374 }
3375
3376 static void
3377 ev_window_cmd_leave_fullscreen (GtkAction *action, EvWindow *window)
3378 {
3379         ev_window_stop_fullscreen (window, TRUE);
3380 }
3381
3382 static void
3383 ev_window_cmd_start_presentation (GtkAction *action, EvWindow *window)
3384 {
3385         ev_window_run_presentation (window);
3386 }
3387
3388 void
3389 ev_window_start_presentation (EvWindow *ev_window)
3390 {
3391         ev_window_run_presentation (ev_window);
3392 }
3393
3394 static gboolean
3395 ev_window_enumerate_printer_cb (GtkPrinter *printer,
3396                                 EvWindow   *window)
3397 {
3398         EvWindowPrivate *priv = window->priv;
3399         const gchar *printer_name;
3400
3401         printer_name = gtk_print_settings_get_printer (priv->print_settings);
3402         if ((printer_name
3403              && strcmp (printer_name, gtk_printer_get_name (printer)) == 0) ||
3404             (!printer_name && gtk_printer_is_default (printer))) {
3405                 if (priv->printer)
3406                         g_object_unref (priv->printer);
3407                 priv->printer = g_object_ref (printer);
3408
3409                 /* Now that we have the printer, we'll start the print */
3410                 ev_window_do_preview_print (window);
3411
3412                 return TRUE; /* we're done */
3413         }
3414
3415         return FALSE; /* continue the enumeration */
3416 }
3417
3418 static void
3419 ev_window_preview_print_finished (GtkPrintJob *print_job,
3420                                   EvWindow    *window,
3421                                   GError      *error)
3422 {
3423         if (error) {
3424                 GtkWidget *dialog;
3425
3426                 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
3427                                                  GTK_DIALOG_MODAL,
3428                                                  GTK_MESSAGE_ERROR,
3429                                                  GTK_BUTTONS_OK,
3430                                                  _("Failed to print document"));
3431                 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
3432                                                           "%s", error->message);
3433
3434                 gtk_dialog_run (GTK_DIALOG (dialog));
3435                 gtk_widget_destroy (dialog);
3436         }
3437
3438         g_object_unref (print_job);
3439         gtk_widget_destroy (GTK_WIDGET (window));
3440 }
3441
3442 static void
3443 ev_window_do_preview_print (EvWindow *window)
3444 {
3445         EvWindowPrivate  *priv = window->priv;
3446         GtkPageSetup     *page_setup;
3447         GtkPrintJob      *job;
3448         gchar            *filename;
3449         GError           *error = NULL;
3450
3451         g_assert (priv->print_settings != NULL);
3452         g_assert (priv->printer != NULL);
3453
3454         page_setup = gtk_page_setup_new ();
3455
3456         job = gtk_print_job_new (gtk_window_get_title (GTK_WINDOW (window)),
3457                                  priv->printer,
3458                                  priv->print_settings,
3459                                  page_setup);
3460
3461         g_object_unref (priv->print_settings);
3462         priv->print_settings = NULL;
3463         g_object_unref (priv->printer);
3464         priv->printer = NULL;
3465         g_object_unref (page_setup);
3466
3467         filename = g_filename_from_uri (priv->local_uri ?
3468                                         priv->local_uri : priv->uri,
3469                                         NULL, NULL);
3470
3471         if (gtk_print_job_set_source_file (job, filename, &error)) {
3472                 gtk_print_job_send (job,
3473                                     (GtkPrintJobCompleteFunc)ev_window_preview_print_finished,
3474                                     window, NULL);
3475         } else {
3476                 g_warning ("%s", error->message);
3477                 g_error_free (error);
3478         }
3479
3480         g_free (filename);
3481
3482         gtk_widget_hide (GTK_WIDGET (window));
3483 }
3484
3485 static void
3486 ev_window_cmd_preview_print (GtkAction *action, EvWindow *window)
3487 {
3488         EvWindowPrivate *priv = window->priv;
3489         GtkPrintSettings *print_settings = NULL;
3490 #if GTK_CHECK_VERSION (2, 11, 0)
3491         const gchar      *print_settings_file = priv->print_settings_file;
3492
3493         if (print_settings_file) {
3494                 if (g_file_test (print_settings_file, G_FILE_TEST_IS_REGULAR)) {
3495                         GError *error = NULL;
3496
3497                         print_settings = gtk_print_settings_new_from_file (print_settings_file,
3498                                                                            &error);
3499                         
3500                         if (error) {
3501                                 g_warning ("%s", error->message);
3502                                 g_error_free (error);
3503                                 print_settings = NULL;
3504                         }
3505                 }
3506         }
3507 #endif /* GTK 2.11.0 */
3508         
3509         if (!print_settings)
3510                 print_settings = gtk_print_settings_new ();
3511
3512         if (priv->print_settings)
3513                 g_object_unref (priv->print_settings);
3514         priv->print_settings = print_settings;
3515
3516         gtk_enumerate_printers ((GtkPrinterFunc) ev_window_enumerate_printer_cb,
3517                                 window, NULL, FALSE);
3518 }
3519
3520 static void
3521 ev_window_cmd_escape (GtkAction *action, EvWindow *window)
3522 {
3523         GtkWidget *widget;
3524
3525         ev_view_autoscroll_stop (EV_VIEW (window->priv->view));
3526         
3527         widget = gtk_window_get_focus (GTK_WINDOW (window));
3528         if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) {
3529                 update_chrome_flag (window, EV_CHROME_FINDBAR, FALSE);
3530                 update_chrome_visibility (window);
3531                 gtk_widget_grab_focus (window->priv->view);
3532         } else {
3533                 gboolean fullscreen;
3534                 gboolean presentation;
3535
3536                 g_object_get (window->priv->view,
3537                               "fullscreen", &fullscreen,
3538                               "presentation", &presentation,
3539                               NULL);
3540
3541                 if (fullscreen) {
3542                         ev_window_stop_fullscreen (window, TRUE);
3543                 } else if (presentation) {
3544                         ev_window_stop_presentation (window, TRUE);
3545                         gtk_widget_grab_focus (window->priv->view);
3546                 } else {
3547                         gtk_widget_grab_focus (window->priv->view);
3548                 }
3549
3550                 if (fullscreen && presentation)
3551                         g_warning ("Both fullscreen and presentation set somehow");
3552         }
3553 }
3554
3555 static void
3556 save_sizing_mode (EvWindow *window)
3557 {
3558         EvSizingMode mode;
3559         GEnumValue *enum_value;
3560
3561         mode = ev_view_get_sizing_mode (EV_VIEW (window->priv->view));
3562         enum_value = g_enum_get_value (EV_SIZING_MODE_CLASS, mode);
3563
3564         if (!ev_window_is_empty (window))
3565                 ev_metadata_manager_set_string (window->priv->uri, "sizing_mode",
3566                                                 enum_value->value_nick);
3567 }
3568
3569 static void     
3570 ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec,
3571                                   EvWindow   *ev_window)
3572 {
3573         GtkWidget *scrolled_window;
3574         EvSizingMode sizing_mode;
3575
3576         g_object_get (ev_window->priv->view,
3577                       "sizing-mode", &sizing_mode,
3578                       NULL);
3579
3580         scrolled_window = ev_window->priv->scrolled_window;
3581
3582         g_signal_handlers_disconnect_by_func (ev_window->priv->view, ev_view_update_view_size, scrolled_window);
3583
3584         if (sizing_mode != EV_SIZING_FREE)
3585                 ev_view_update_view_size (EV_VIEW (ev_window->priv->view),
3586                                           GTK_SCROLLED_WINDOW (scrolled_window));
3587
3588         switch (sizing_mode) {
3589                 case EV_SIZING_BEST_FIT:
3590                         g_object_set (G_OBJECT (scrolled_window),
3591                                       "hscrollbar-policy", GTK_POLICY_NEVER,
3592                                       "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
3593                                       NULL);
3594                         g_signal_connect (ev_window->priv->view, "zoom_invalid",
3595                                           G_CALLBACK (ev_view_update_view_size),
3596                                           scrolled_window);
3597                         break;
3598                 case EV_SIZING_FIT_WIDTH:
3599                         g_object_set (G_OBJECT (scrolled_window),
3600                                       "hscrollbar-policy", GTK_POLICY_NEVER,
3601                                       "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
3602                                       NULL);
3603                         g_signal_connect (ev_window->priv->view, "zoom_invalid",
3604                                           G_CALLBACK (ev_view_update_view_size),
3605                                           scrolled_window);
3606                         break;
3607                 case EV_SIZING_FREE:
3608                         g_object_set (G_OBJECT (scrolled_window),
3609                                       "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
3610                                       "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
3611                                       NULL);
3612                         break;
3613         }
3614
3615         update_sizing_buttons (ev_window);
3616         save_sizing_mode (ev_window);
3617 }
3618
3619 static void     
3620 ev_window_zoom_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window)
3621 {
3622         ev_window_update_actions (ev_window);
3623
3624         if (ev_view_get_sizing_mode (view) == EV_SIZING_FREE && !ev_window_is_empty (ev_window)) {
3625                 gdouble zoom;
3626
3627                 zoom = ev_view_get_zoom (view);
3628                 zoom *= 72.0 / get_screen_dpi (GTK_WINDOW(ev_window));
3629                 ev_metadata_manager_set_double (ev_window->priv->uri, "zoom", zoom);
3630         }
3631 }
3632
3633 static void
3634 ev_window_update_continuous_action (EvWindow *window)
3635 {
3636         GtkAction *action;
3637
3638         action = gtk_action_group_get_action (window->priv->action_group, "ViewContinuous");
3639         g_signal_handlers_block_by_func
3640                 (action, G_CALLBACK (ev_window_cmd_continuous), window);
3641         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
3642                                       ev_view_get_continuous (EV_VIEW (window->priv->view)));
3643         g_signal_handlers_unblock_by_func
3644                 (action, G_CALLBACK (ev_window_cmd_continuous), window);
3645 }
3646
3647 static void
3648 ev_window_update_dual_page_action (EvWindow *window)
3649 {
3650         GtkAction *action;
3651
3652         action = gtk_action_group_get_action (window->priv->action_group, "ViewDual");
3653         g_signal_handlers_block_by_func
3654                 (action, G_CALLBACK (ev_window_cmd_dual), window);
3655         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
3656                                       ev_view_get_dual_page (EV_VIEW (window->priv->view)));
3657         g_signal_handlers_unblock_by_func
3658                 (action, G_CALLBACK (ev_window_cmd_dual), window);
3659 }
3660
3661 static void     
3662 ev_window_continuous_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window)
3663 {
3664         ev_window_update_continuous_action (ev_window);
3665
3666         if (!ev_window_is_empty (ev_window))
3667                 ev_metadata_manager_set_boolean (ev_window->priv->uri, "continuous",
3668                                                  ev_view_get_continuous (EV_VIEW (ev_window->priv->view)));
3669 }
3670
3671 static void     
3672 ev_window_rotation_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *window)
3673 {
3674         int rotation;
3675
3676         rotation = ev_view_get_rotation (EV_VIEW (window->priv->view));
3677
3678         if (!ev_window_is_empty (window))
3679                 ev_metadata_manager_set_int (window->priv->uri, "rotation",
3680                                              rotation);
3681
3682         ev_sidebar_thumbnails_refresh (EV_SIDEBAR_THUMBNAILS (window->priv->sidebar_thumbs),
3683                                        rotation);
3684         ev_window_refresh_window_thumbnail (window, rotation);
3685 }
3686
3687 static void
3688 ev_window_has_selection_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *window)
3689 {
3690         ev_window_update_actions (window);
3691 }
3692
3693 static void     
3694 ev_window_dual_mode_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window)
3695 {
3696         ev_window_update_dual_page_action (ev_window);
3697
3698         if (!ev_window_is_empty (ev_window))
3699                 ev_metadata_manager_set_boolean (ev_window->priv->uri, "dual-page",
3700                                                  ev_view_get_dual_page (EV_VIEW (ev_window->priv->view)));
3701 }
3702
3703 static char *
3704 build_comments_string (void)
3705 {
3706 #ifdef ENABLE_PDF
3707         PopplerBackend backend;
3708         const char *backend_name;
3709         const char *version;
3710
3711         backend = poppler_get_backend ();
3712         version = poppler_get_version ();
3713         switch (backend) {
3714                 case POPPLER_BACKEND_CAIRO:
3715                         backend_name = "cairo";
3716                         break;
3717                 case POPPLER_BACKEND_SPLASH:
3718                         backend_name = "splash";
3719                         break;
3720                 default:
3721                         backend_name = "unknown";
3722                         break;
3723         }
3724
3725         return g_strdup_printf (_("Document Viewer.\n"
3726                                   "Using poppler %s (%s)"),
3727                                 version, backend_name);
3728 #else
3729         return g_strdup_printf (_("Document Viewer"));
3730 #endif
3731 }
3732
3733 static void
3734 ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window)
3735 {
3736         const char *authors[] = {
3737                 "Martin Kretzschmar <m_kretzschmar@gmx.net>",
3738                 "Jonathan Blandford <jrb@gnome.org>",
3739                 "Marco Pesenti Gritti <marco@gnome.org>",
3740                 "Nickolay V. Shmyrev <nshmyrev@yandex.ru>",
3741                 "Bryan Clark <clarkbw@gnome.org>",
3742                 "Carlos Garcia Campos <carlosgc@gnome.org>",
3743                 "Wouter Bolsterlee <wbolster@gnome.org>",
3744                 NULL
3745         };
3746
3747         const char *documenters[] = {
3748                 "Nickolay V. Shmyrev <nshmyrev@yandex.ru>",
3749                 NULL
3750         };
3751
3752         const char *license[] = {
3753                 N_("Evince is free software; you can redistribute it and/or modify "
3754                    "it under the terms of the GNU General Public License as published by "
3755                    "the Free Software Foundation; either version 2 of the License, or "
3756                    "(at your option) any later version.\n"),
3757                 N_("Evince is distributed in the hope that it will be useful, "
3758                    "but WITHOUT ANY WARRANTY; without even the implied warranty of "
3759                    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the "
3760                    "GNU General Public License for more details.\n"),
3761                 N_("You should have received a copy of the GNU General Public License "
3762                    "along with Evince; if not, write to the Free Software Foundation, Inc., "
3763                    "59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n")
3764         };
3765
3766         char *license_trans;
3767         char *comments;
3768
3769 #ifdef ENABLE_NLS
3770         const char **p;
3771
3772         for (p = authors; *p; ++p)
3773                 *p = _(*p);
3774
3775         for (p = documenters; *p; ++p)
3776                 *p = _(*p);
3777 #endif
3778
3779         license_trans = g_strconcat (_(license[0]), "\n", _(license[1]), "\n",
3780                                      _(license[2]), "\n", NULL);
3781         comments = build_comments_string ();
3782
3783         gtk_show_about_dialog (
3784                 GTK_WINDOW (ev_window),
3785                 "name", _("Evince"),
3786                 "version", VERSION,
3787                 "copyright",
3788                 _("\xc2\xa9 1996-2007 The Evince authors"),
3789                 "license", license_trans,
3790                 "website", "http://www.gnome.org/projects/evince",
3791                 "comments", comments,
3792                 "authors", authors,
3793                 "documenters", documenters,
3794                 "translator-credits", _("translator-credits"),
3795                 "logo-icon-name", "evince",
3796                 "wrap-license", TRUE,
3797                 NULL);
3798
3799         g_free (comments);
3800         g_free (license_trans);
3801 }
3802
3803 static void
3804 ev_window_view_toolbar_cb (GtkAction *action, EvWindow *ev_window)
3805 {
3806         gboolean active;
3807         
3808         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
3809         update_chrome_flag (ev_window, EV_CHROME_TOOLBAR, active);
3810         update_chrome_visibility (ev_window);
3811         ev_metadata_manager_set_boolean (NULL, "show_toolbar", active);
3812 }
3813
3814 static void
3815 ev_window_view_sidebar_cb (GtkAction *action, EvWindow *ev_window)
3816 {
3817         if (ev_view_get_presentation (EV_VIEW (ev_window->priv->view)))
3818                 return;
3819             
3820         update_chrome_flag (ev_window, EV_CHROME_SIDEBAR,
3821                             gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
3822         update_chrome_visibility (ev_window);
3823 }
3824
3825 static void
3826 ev_window_sidebar_current_page_changed_cb (EvSidebar  *ev_sidebar,
3827                                            GParamSpec *pspec,
3828                                            EvWindow   *ev_window)
3829 {
3830         GtkWidget *current_page;
3831         const char *id;
3832
3833         g_object_get (G_OBJECT (ev_sidebar), "current_page", &current_page, NULL);
3834
3835         if (current_page == ev_window->priv->sidebar_links) {
3836                 id = LINKS_SIDEBAR_ID;
3837         } else if (current_page == ev_window->priv->sidebar_thumbs) {
3838                 id = THUMBNAILS_SIDEBAR_ID;
3839         } else if (current_page == ev_window->priv->sidebar_attachments) {
3840                 id = ATTACHMENTS_SIDEBAR_ID;
3841         } else {
3842                 g_assert_not_reached();
3843         }
3844
3845         g_object_unref (current_page);
3846
3847         if (!ev_window_is_empty (ev_window))
3848                 ev_metadata_manager_set_string (ev_window->priv->uri, "sidebar_page", id);
3849 }
3850
3851 static void
3852 ev_window_sidebar_visibility_changed_cb (EvSidebar  *ev_sidebar,
3853                                          GParamSpec *pspec,
3854                                          EvWindow   *ev_window)
3855 {
3856         EvView *view = EV_VIEW (ev_window->priv->view);
3857         GtkAction *action;
3858
3859         action = gtk_action_group_get_action (ev_window->priv->action_group, "ViewSidebar");
3860
3861         if (!ev_view_get_presentation (view)) {
3862                 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
3863                                               GTK_WIDGET_VISIBLE (ev_sidebar));
3864
3865                 ev_metadata_manager_set_boolean (ev_window->priv->uri, "sidebar_visibility",
3866                                                  GTK_WIDGET_VISIBLE (ev_sidebar));
3867         }
3868 }
3869
3870 static void
3871 view_menu_link_popup (EvWindow *ev_window,
3872                       EvLink   *link)
3873 {
3874         gboolean   show_external = FALSE;
3875         gboolean   show_internal = FALSE;
3876         GtkAction *action;
3877         
3878         if (ev_window->priv->link)
3879                 g_object_unref (ev_window->priv->link);
3880         
3881         if (link)
3882                 ev_window->priv->link = g_object_ref (link);
3883         else    
3884                 ev_window->priv->link = NULL;
3885
3886         if (ev_window->priv->link) {
3887                 EvLinkAction *ev_action;
3888
3889                 ev_action = ev_link_get_action (link);
3890                 if (ev_action) {
3891                         switch (ev_link_action_get_action_type (ev_action)) {
3892                                 case EV_LINK_ACTION_TYPE_GOTO_DEST:
3893                                 case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
3894                                         show_internal = TRUE;
3895                                         break;
3896                                 case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
3897                                 case EV_LINK_ACTION_TYPE_LAUNCH:
3898                                         show_external = TRUE;
3899                                         break;
3900                                 default:
3901                                         break;
3902                         }
3903                 }
3904         }
3905         
3906         action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
3907                                               "OpenLink");
3908         gtk_action_set_visible (action, show_external);
3909
3910         action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
3911                                               "CopyLinkAddress");
3912         gtk_action_set_visible (action, show_external);
3913
3914         action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
3915                                               "GoLink");
3916         gtk_action_set_visible (action, show_internal);
3917
3918         action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
3919                                               "OpenLinkNewWindow");
3920         gtk_action_set_visible (action, show_internal);
3921 }
3922
3923 static void
3924 view_menu_image_popup (EvWindow  *ev_window,
3925                        EvImage   *image)
3926 {
3927         GtkAction *action;
3928         gboolean   show_image = FALSE;
3929         
3930         if (ev_window->priv->image)
3931                 g_object_unref (ev_window->priv->image);
3932         
3933         if (image)
3934                 ev_window->priv->image = g_object_ref (image);
3935         else    
3936                 ev_window->priv->image = NULL;
3937
3938         show_image = (ev_window->priv->image != NULL);
3939         
3940         action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
3941                                               "SaveImageAs");
3942         gtk_action_set_visible (action, show_image);
3943
3944         action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
3945                                               "CopyImage");
3946         gtk_action_set_visible (action, show_image);
3947 }
3948
3949 static gboolean
3950 view_menu_popup_cb (EvView   *view,
3951                     GObject  *object,
3952                     EvWindow *ev_window)
3953 {
3954         if (ev_view_get_presentation (EV_VIEW (ev_window->priv->view)))
3955                 return FALSE;
3956
3957         view_menu_link_popup (ev_window,
3958                               EV_IS_LINK (object) ? EV_LINK (object) : NULL);
3959         view_menu_image_popup (ev_window,
3960                                EV_IS_IMAGE (object) ? EV_IMAGE (object) : NULL);
3961         
3962         gtk_menu_popup (GTK_MENU (ev_window->priv->view_popup),
3963                         NULL, NULL, NULL, NULL,
3964                         3, gtk_get_current_event_time ());
3965         return TRUE;
3966 }
3967
3968 static gboolean
3969 attachment_bar_menu_popup_cb (EvSidebarAttachments *attachbar,
3970                               GList           *attach_list,
3971                               EvWindow        *ev_window)
3972 {
3973         GtkWidget *popup;
3974
3975         g_assert (attach_list != NULL);
3976
3977         if (ev_window->priv->attach_list) {
3978                 g_list_foreach (ev_window->priv->attach_list,
3979                                 (GFunc) g_object_unref, NULL);
3980                 g_list_free (ev_window->priv->attach_list);
3981         }
3982         
3983         ev_window->priv->attach_list = attach_list;
3984         
3985         popup = ev_window->priv->attachment_popup;
3986
3987         gtk_menu_popup (GTK_MENU (popup), NULL, NULL,
3988                         NULL, NULL,
3989                         3, gtk_get_current_event_time ());
3990
3991         return TRUE;
3992 }
3993
3994 static void
3995 view_find_status_changed_cb (EvView     *view,
3996                              GParamSpec *pspec,
3997                              EvWindow   *ev_window)
3998 {
3999         const char *text;
4000
4001         text = ev_view_get_find_status (view);
4002         egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar),
4003                                       text);
4004 }
4005
4006 static void
4007 find_bar_previous_cb (EggFindBar *find_bar,
4008                       EvWindow   *ev_window)
4009 {
4010         ev_view_find_previous (EV_VIEW (ev_window->priv->view));
4011 }
4012
4013 static void
4014 find_bar_next_cb (EggFindBar *find_bar,
4015                   EvWindow   *ev_window)
4016 {
4017         ev_view_find_next (EV_VIEW (ev_window->priv->view));
4018 }
4019
4020 static void
4021 find_bar_close_cb (EggFindBar *find_bar,
4022                    EvWindow   *ev_window)
4023 {
4024         ev_view_find_cancel (EV_VIEW (ev_window->priv->view));
4025         update_chrome_flag (ev_window, EV_CHROME_FINDBAR, FALSE);
4026         update_chrome_visibility (ev_window);
4027 }
4028
4029 static void
4030 find_bar_search_changed_cb (EggFindBar *find_bar,
4031                             GParamSpec *param,
4032                             EvWindow   *ev_window)
4033 {
4034         gboolean case_sensitive;
4035         const char *search_string;
4036
4037         /* Either the string or case sensitivity could have changed. */
4038
4039         case_sensitive = egg_find_bar_get_case_sensitive (find_bar);
4040         search_string = egg_find_bar_get_search_string (find_bar);
4041
4042         ev_view_search_changed (EV_VIEW(ev_window->priv->view));
4043
4044         if (ev_window->priv->document &&
4045             EV_IS_DOCUMENT_FIND (ev_window->priv->document)) {
4046                 if (search_string && search_string[0]) {
4047                         ev_document_doc_mutex_lock ();
4048                         ev_document_find_begin (EV_DOCUMENT_FIND (ev_window->priv->document), 
4049                                                 ev_page_cache_get_current_page (ev_window->priv->page_cache),
4050                                                 search_string,
4051                                                 case_sensitive);
4052                         ev_document_doc_mutex_unlock ();
4053                 } else {
4054                         ev_document_doc_mutex_lock ();
4055                         ev_document_find_cancel (EV_DOCUMENT_FIND (ev_window->priv->document));
4056                         ev_document_doc_mutex_unlock ();
4057
4058                         ev_window_update_actions (ev_window);
4059                         egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar),
4060                                                       NULL);
4061                         gtk_widget_queue_draw (GTK_WIDGET (ev_window->priv->view));
4062                 }
4063         }
4064 }
4065
4066 static void
4067 find_bar_visibility_changed_cb (EggFindBar *find_bar,
4068                             GParamSpec *param,
4069                             EvWindow   *ev_window)
4070 {
4071         gboolean visible;
4072
4073         visible = GTK_WIDGET_VISIBLE (find_bar);
4074
4075         if (ev_window->priv->document &&
4076             EV_IS_DOCUMENT_FIND (ev_window->priv->document)) {
4077                 ev_view_set_highlight_search (EV_VIEW(ev_window->priv->view), visible);
4078                 ev_view_search_changed (EV_VIEW(ev_window->priv->view));
4079                 ev_window_update_actions (ev_window);
4080
4081                 if (!visible)
4082                         egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar), NULL);
4083         }
4084 }
4085
4086 static void
4087 find_bar_scroll(EggFindBar *find_bar, GtkScrollType scroll, EvWindow* ev_window)
4088 {
4089         ev_view_scroll(EV_VIEW(ev_window->priv->view), scroll, FALSE);
4090 }
4091
4092 static void
4093 zoom_control_changed_cb (EphyZoomAction *action,
4094                          float           zoom,
4095                          EvWindow       *ev_window)
4096 {
4097         EvSizingMode mode;
4098         
4099         g_return_if_fail (EV_IS_WINDOW (ev_window));
4100
4101         if (zoom == EPHY_ZOOM_BEST_FIT) {
4102                 mode = EV_SIZING_BEST_FIT;
4103         } else if (zoom == EPHY_ZOOM_FIT_WIDTH) {
4104                 mode = EV_SIZING_FIT_WIDTH;
4105         } else {
4106                 mode = EV_SIZING_FREE;
4107         }
4108         
4109         ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), mode);
4110         
4111         if (mode == EV_SIZING_FREE) {
4112                 ev_view_set_zoom (EV_VIEW (ev_window->priv->view),
4113                                   zoom * get_screen_dpi (GTK_WINDOW (ev_window)) / 72.0,
4114                                   FALSE);
4115         }
4116 }
4117
4118 static void
4119 ev_window_finalize (GObject *object)
4120 {
4121         GList *windows = ev_application_get_windows (EV_APP);
4122
4123         if (windows == NULL) {
4124                 ev_application_shutdown (EV_APP);
4125         } else {
4126                 g_list_free (windows);
4127         }
4128         
4129         G_OBJECT_CLASS (ev_window_parent_class)->finalize (object);
4130 }
4131
4132 static void
4133 ev_window_dispose (GObject *object)
4134 {
4135         EvWindow *window = EV_WINDOW (object);
4136         EvWindowPrivate *priv = window->priv;
4137 #ifdef ENABLE_DBUS
4138         GObject *keys;
4139
4140         keys = ev_application_get_media_keys (EV_APP);
4141         if (keys) {
4142                 ev_media_player_keys_focused (EV_MEDIA_PLAYER_KEYS (keys), NULL);
4143                 g_object_unref (keys);
4144         }
4145 #endif /* ENABLE_DBUS */
4146
4147         if (priv->monitor) {
4148                 g_object_unref (priv->monitor);
4149                 priv->monitor = NULL;
4150         }
4151         
4152         if (priv->title) {
4153                 ev_window_title_free (priv->title);
4154                 priv->title = NULL;
4155         }
4156
4157         if (priv->ui_manager) {
4158                 g_object_unref (priv->ui_manager);
4159                 priv->ui_manager = NULL;
4160         }
4161
4162         if (priv->action_group) {
4163                 g_object_unref (priv->action_group);
4164                 priv->action_group = NULL;
4165         }
4166
4167         if (priv->view_popup_action_group) {
4168                 g_object_unref (priv->view_popup_action_group);
4169                 priv->view_popup_action_group = NULL;
4170         }
4171
4172         if (priv->attachment_popup_action_group) {
4173                 g_object_unref (priv->attachment_popup_action_group);
4174                 priv->attachment_popup_action_group = NULL;
4175         }
4176
4177         if (priv->recent_action_group) {
4178                 g_object_unref (priv->recent_action_group);
4179                 priv->recent_action_group = NULL;
4180         }
4181
4182         if (priv->recent_manager) {
4183                 g_signal_handlers_disconnect_by_func (priv->recent_manager,
4184                                                       ev_window_setup_recent,
4185                                                       window);
4186                 priv->recent_manager = NULL;
4187         }
4188
4189         priv->recent_ui_id = 0;
4190
4191         if (priv->page_cache) {
4192                 g_signal_handlers_disconnect_by_func (priv->page_cache, page_changed_cb, window);
4193                 priv->page_cache = NULL;
4194         }
4195
4196         if (priv->document) {
4197                 g_object_unref (priv->document);
4198                 priv->document = NULL;
4199         }
4200         
4201         if (priv->view) {
4202                 g_object_unref (priv->view);
4203                 priv->view = NULL;
4204         }
4205
4206         if (priv->password_view) {
4207                 g_object_unref (priv->password_view);
4208                 priv->password_view = NULL;
4209         }
4210
4211         if (priv->load_job) {
4212                 ev_window_clear_load_job (window);
4213         }
4214
4215         if (priv->reload_job) {
4216                 ev_window_clear_reload_job (window);
4217         }
4218
4219         if (priv->save_job) {
4220                 ev_window_clear_save_job (window);
4221         }
4222
4223         if (priv->thumbnail_job) {
4224                 ev_window_clear_thumbnail_job (window);
4225         }
4226         
4227         if (priv->local_uri) {
4228                 ev_window_clear_local_uri (window);
4229                 priv->local_uri = NULL;
4230         }
4231         
4232         ev_window_close_dialogs (window);
4233         ev_window_clear_print_job (window);
4234
4235         if (window->priv->gtk_print_job) {
4236                 g_object_unref (window->priv->gtk_print_job);
4237                 window->priv->gtk_print_job = NULL;
4238         }
4239         
4240         if (window->priv->printer) {
4241                 g_object_unref (window->priv->printer);
4242                 window->priv->printer = NULL;
4243         }
4244
4245         if (window->priv->print_settings) {
4246                 g_object_unref (window->priv->print_settings);
4247                 window->priv->print_settings = NULL;
4248         }
4249
4250         if (window->priv->print_page_setup) {
4251                 g_object_unref (window->priv->print_page_setup);
4252                 window->priv->print_page_setup = NULL;
4253         }
4254
4255         if (priv->link) {
4256                 g_object_unref (priv->link);
4257                 priv->link = NULL;
4258         }
4259
4260         if (priv->image) {
4261                 g_object_unref (priv->image);
4262                 priv->image = NULL;
4263         }
4264
4265         if (priv->attach_list) {
4266                 g_list_foreach (priv->attach_list,
4267                                 (GFunc) g_object_unref,
4268                                 NULL);
4269                 g_list_free (priv->attach_list);
4270                 priv->attach_list = NULL;
4271         }
4272
4273         if (priv->find_bar) {
4274                 g_signal_handlers_disconnect_by_func
4275                         (window->priv->find_bar,
4276                          G_CALLBACK (find_bar_close_cb),
4277                          window);
4278                 priv->find_bar = NULL;
4279         }
4280
4281         if (priv->uri) {
4282                 if (priv->unlink_temp_file)
4283                         ev_window_clear_temp_file (window);
4284                 g_free (priv->uri);
4285                 priv->uri = NULL;
4286         }
4287
4288         if (priv->dest) {
4289                 g_object_unref (priv->dest);
4290                 priv->dest = NULL;
4291         }
4292
4293         if (priv->history) {
4294                 g_object_unref (priv->history);
4295                 priv->history = NULL;
4296         }
4297
4298         if (priv->print_settings_file) {
4299                 ev_window_clear_print_settings_file (window);
4300                 priv->print_settings_file = NULL;
4301         }
4302
4303         if (priv->presentation_timeout_id > 0) {
4304                 g_source_remove (priv->presentation_timeout_id);
4305                 priv->presentation_timeout_id = 0;
4306         }
4307
4308         G_OBJECT_CLASS (ev_window_parent_class)->dispose (object);
4309 }
4310
4311 static void
4312 ev_window_class_init (EvWindowClass *ev_window_class)
4313 {
4314         GObjectClass *g_object_class = G_OBJECT_CLASS (ev_window_class);
4315         GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (ev_window_class);
4316
4317         g_object_class->dispose = ev_window_dispose;
4318         g_object_class->finalize = ev_window_finalize;
4319
4320         widget_class->screen_changed = ev_window_screen_changed;
4321
4322         g_type_class_add_private (g_object_class, sizeof (EvWindowPrivate));
4323 }
4324
4325 /* Normal items */
4326 static const GtkActionEntry entries[] = {
4327         { "File", NULL, N_("_File") },
4328         { "Edit", NULL, N_("_Edit") },
4329         { "View", NULL, N_("_View") },
4330         { "Go", NULL, N_("_Go") },
4331         { "Help", NULL, N_("_Help") },
4332
4333         /* File menu */
4334         { "FileOpen", GTK_STOCK_OPEN, N_("_Open..."), "<control>O",
4335           N_("Open an existing document"),
4336           G_CALLBACK (ev_window_cmd_file_open) },
4337         { "FileOpenCopy", NULL, N_("Op_en a Copy"), "<control>N",
4338           N_("Open a copy of the current document in a new window"),
4339           G_CALLBACK (ev_window_cmd_file_open_copy) },
4340         { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), "<control>S",
4341           N_("Save a copy of the current document"),
4342           G_CALLBACK (ev_window_cmd_save_as) },
4343         { "FilePrintSetup", NULL, N_("Print Set_up..."), NULL,
4344           N_("Setup the page settings for printing"),
4345           G_CALLBACK (ev_window_cmd_file_print_setup) },
4346         { "FilePrint", GTK_STOCK_PRINT, N_("_Print..."), "<control>P",
4347           N_("Print this document"),
4348           G_CALLBACK (ev_window_cmd_file_print) },
4349         { "FileProperties", GTK_STOCK_PROPERTIES, N_("P_roperties"), "<alt>Return", NULL,
4350           G_CALLBACK (ev_window_cmd_file_properties) },                       
4351         { "FileCloseWindow", GTK_STOCK_CLOSE, NULL, "<control>W", NULL,
4352           G_CALLBACK (ev_window_cmd_file_close_window) },
4353
4354         /* Edit menu */
4355         { "EditCopy", GTK_STOCK_COPY, NULL, "<control>C", NULL,
4356           G_CALLBACK (ev_window_cmd_edit_copy) },
4357         { "EditSelectAll", GTK_STOCK_SELECT_ALL, N_("Select _All"), "<control>A", NULL,
4358           G_CALLBACK (ev_window_cmd_edit_select_all) },
4359         { "EditFind", GTK_STOCK_FIND, N_("_Find..."), "<control>F",
4360           N_("Find a word or phrase in the document"),
4361           G_CALLBACK (ev_window_cmd_edit_find) },
4362         { "EditFindNext", NULL, N_("Find Ne_xt"), "<control>G", NULL,
4363           G_CALLBACK (ev_window_cmd_edit_find_next) },
4364         { "EditFindPrevious", NULL, N_("Find Pre_vious"), "<shift><control>G", NULL,
4365           G_CALLBACK (ev_window_cmd_edit_find_previous) },
4366         { "EditToolbar", NULL, N_("T_oolbar"), NULL, NULL,
4367           G_CALLBACK (ev_window_cmd_edit_toolbar) },
4368         { "EditRotateLeft", EV_STOCK_ROTATE_LEFT, N_("Rotate _Left"), NULL, NULL,
4369           G_CALLBACK (ev_window_cmd_edit_rotate_left) },
4370         { "EditRotateRight", EV_STOCK_ROTATE_RIGHT, N_("Rotate _Right"), NULL, NULL,
4371           G_CALLBACK (ev_window_cmd_edit_rotate_right) },
4372
4373         /* View menu */
4374         { "ViewZoomIn", GTK_STOCK_ZOOM_IN, NULL, "<control>plus",
4375           N_("Enlarge the document"),
4376           G_CALLBACK (ev_window_cmd_view_zoom_in) },
4377         { "ViewZoomOut", GTK_STOCK_ZOOM_OUT, NULL, "<control>minus",
4378           N_("Shrink the document"),
4379           G_CALLBACK (ev_window_cmd_view_zoom_out) },
4380         { "ViewReload", GTK_STOCK_REFRESH, N_("_Reload"), "<control>R",
4381           N_("Reload the document"),
4382           G_CALLBACK (ev_window_cmd_view_reload) },
4383
4384         { "ViewAutoscroll", GTK_STOCK_MEDIA_PLAY, N_("Auto_scroll"), NULL, NULL,
4385           G_CALLBACK (ev_window_cmd_view_autoscroll) },
4386
4387         /* Go menu */
4388         { "GoPreviousPage", GTK_STOCK_GO_UP, N_("_Previous Page"), "<control>Page_Up",
4389           N_("Go to the previous page"),
4390           G_CALLBACK (ev_window_cmd_go_previous_page) },
4391         { "GoNextPage", GTK_STOCK_GO_DOWN, N_("_Next Page"), "<control>Page_Down",
4392           N_("Go to the next page"),
4393           G_CALLBACK (ev_window_cmd_go_next_page) },
4394         { "GoFirstPage", GTK_STOCK_GOTO_TOP, N_("_First Page"), "<control>Home",
4395           N_("Go to the first page"),
4396           G_CALLBACK (ev_window_cmd_go_first_page) },
4397         { "GoLastPage", GTK_STOCK_GOTO_BOTTOM, N_("_Last Page"), "<control>End",
4398           N_("Go to the last page"),
4399           G_CALLBACK (ev_window_cmd_go_last_page) },
4400
4401         /* Help menu */
4402         { "HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL,
4403           G_CALLBACK (ev_window_cmd_help_contents) },
4404
4405         { "HelpAbout", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL,
4406           G_CALLBACK (ev_window_cmd_help_about) },
4407
4408         /* Toolbar-only */
4409         { "LeaveFullscreen", GTK_STOCK_LEAVE_FULLSCREEN, N_("Leave Fullscreen"), NULL,
4410           N_("Leave fullscreen mode"),
4411           G_CALLBACK (ev_window_cmd_leave_fullscreen) },
4412         { "StartPresentation", EV_STOCK_RUN_PRESENTATION, N_("Start Presentation"), NULL,
4413           N_("Start a presentation"),
4414           G_CALLBACK (ev_window_cmd_start_presentation) },
4415         { "PreviewPrint", GTK_STOCK_PRINT, N_("Print"), NULL,
4416           N_("Print this document"),
4417           G_CALLBACK (ev_window_cmd_preview_print) },
4418
4419         /* Accellerators */
4420         { "Escape", NULL, "", "Escape", "",
4421           G_CALLBACK (ev_window_cmd_escape) },
4422         { "Slash", GTK_STOCK_FIND, NULL, "slash", NULL,
4423           G_CALLBACK (ev_window_cmd_edit_find) },
4424         { "PageDown", NULL, "", "Page_Down", NULL,
4425           G_CALLBACK (ev_window_cmd_scroll_forward) },
4426         { "PageUp", NULL, "", "Page_Up", NULL,
4427           G_CALLBACK (ev_window_cmd_scroll_backward) },
4428         { "Space", NULL, "", "space", NULL,
4429           G_CALLBACK (ev_window_cmd_scroll_forward) },
4430         { "ShiftSpace", NULL, "", "<shift>space", NULL,
4431           G_CALLBACK (ev_window_cmd_scroll_backward) },
4432         { "BackSpace", NULL, "", "BackSpace", NULL,
4433           G_CALLBACK (ev_window_cmd_scroll_backward) },
4434         { "ShiftBackSpace", NULL, "", "<shift>BackSpace", NULL,
4435           G_CALLBACK (ev_window_cmd_scroll_forward) },
4436         { "Return", NULL, "", "Return", NULL,
4437           G_CALLBACK (ev_window_cmd_scroll_forward) },
4438         { "ShiftReturn", NULL, "", "<shift>Return", NULL,
4439           G_CALLBACK (ev_window_cmd_scroll_backward) },
4440         { "Plus", GTK_STOCK_ZOOM_IN, NULL, "plus", NULL,
4441           G_CALLBACK (ev_window_cmd_view_zoom_in) },
4442         { "CtrlEqual", GTK_STOCK_ZOOM_IN, NULL, "<control>equal", NULL,
4443           G_CALLBACK (ev_window_cmd_view_zoom_in) },
4444         { "Equal", GTK_STOCK_ZOOM_IN, NULL, "equal", NULL,
4445           G_CALLBACK (ev_window_cmd_view_zoom_in) },
4446         { "Minus", GTK_STOCK_ZOOM_OUT, NULL, "minus", NULL,
4447           G_CALLBACK (ev_window_cmd_view_zoom_out) },
4448         { "FocusPageSelector", NULL, "", "<control>l", NULL,
4449           G_CALLBACK (ev_window_cmd_focus_page_selector) },
4450         { "GoBackwardFast", NULL, "", "<shift>Page_Up", NULL,
4451           G_CALLBACK (ev_window_cmd_go_backward) },
4452         { "GoForwardFast", NULL, "", "<shift>Page_Down", NULL,
4453           G_CALLBACK (ev_window_cmd_go_forward) },
4454         { "KpPlus", GTK_STOCK_ZOOM_IN, NULL, "KP_Add", NULL,
4455           G_CALLBACK (ev_window_cmd_view_zoom_in) },
4456         { "KpMinus", GTK_STOCK_ZOOM_OUT, NULL, "KP_Subtract", NULL,
4457           G_CALLBACK (ev_window_cmd_view_zoom_out) },
4458         { "CtrlKpPlus", GTK_STOCK_ZOOM_IN, NULL, "<control>KP_Add", NULL,
4459           G_CALLBACK (ev_window_cmd_view_zoom_in) },
4460         { "CtrlKpMinus", GTK_STOCK_ZOOM_OUT, NULL, "<control>KP_Subtract", NULL,
4461           G_CALLBACK (ev_window_cmd_view_zoom_out) },
4462         { "CtrlInsert", GTK_STOCK_COPY, NULL, "<control>Insert", NULL,
4463           G_CALLBACK (ev_window_cmd_edit_copy) },
4464 };
4465
4466 /* Toggle items */
4467 static const GtkToggleActionEntry toggle_entries[] = {
4468         /* View Menu */
4469         { "ViewToolbar", NULL, N_("_Toolbar"), NULL,
4470           N_("Show or hide the toolbar"),
4471           G_CALLBACK (ev_window_view_toolbar_cb), TRUE },
4472         { "ViewSidebar", GTK_STOCK_INDEX, N_("Side _Pane"), "F9",
4473           N_("Show or hide the side pane"),
4474           G_CALLBACK (ev_window_view_sidebar_cb), TRUE },
4475         { "ViewContinuous", EV_STOCK_VIEW_CONTINUOUS, N_("_Continuous"), NULL,
4476           N_("Show the entire document"),
4477           G_CALLBACK (ev_window_cmd_continuous), TRUE },
4478         { "ViewDual", EV_STOCK_VIEW_DUAL, N_("_Dual"), NULL,
4479           N_("Show two pages at once"),
4480           G_CALLBACK (ev_window_cmd_dual), FALSE },
4481         { "ViewFullscreen", GTK_STOCK_FULLSCREEN, N_("_Fullscreen"), "F11",
4482           N_("Expand the window to fill the screen"),
4483           G_CALLBACK (ev_window_cmd_view_fullscreen) },
4484         { "ViewPresentation", EV_STOCK_RUN_PRESENTATION, N_("Pre_sentation"), "F5",
4485           N_("Run document as a presentation"),
4486           G_CALLBACK (ev_window_cmd_view_presentation) },
4487         { "ViewBestFit", EV_STOCK_ZOOM_PAGE, N_("_Best Fit"), NULL,
4488           N_("Make the current document fill the window"),
4489           G_CALLBACK (ev_window_cmd_view_best_fit) },
4490         { "ViewPageWidth", EV_STOCK_ZOOM_WIDTH, N_("Fit Page _Width"), NULL,
4491           N_("Make the current document fill the window width"),
4492           G_CALLBACK (ev_window_cmd_view_page_width) },
4493 };
4494
4495 /* Popups specific items */
4496 static const GtkActionEntry view_popup_entries [] = {
4497         /* Links */
4498         { "OpenLink", GTK_STOCK_OPEN, N_("_Open Link"), NULL,
4499           NULL, G_CALLBACK (ev_view_popup_cmd_open_link) },
4500         { "GoLink", GTK_STOCK_GO_FORWARD, N_("_Go To"), NULL,
4501           NULL, G_CALLBACK (ev_view_popup_cmd_open_link) },
4502         { "OpenLinkNewWindow", NULL, N_("Open in New _Window"), NULL,
4503           NULL, G_CALLBACK (ev_view_popup_cmd_open_link_new_window) },
4504         { "CopyLinkAddress", NULL, N_("_Copy Link Address"), NULL,
4505           NULL, G_CALLBACK (ev_view_popup_cmd_copy_link_address) },
4506         { "SaveImageAs", NULL, N_("_Save Image As..."), NULL,
4507           NULL, G_CALLBACK (ev_view_popup_cmd_save_image_as) },
4508         { "CopyImage", NULL, N_("Copy _Image"), NULL,
4509           NULL, G_CALLBACK (ev_view_popup_cmd_copy_image) },
4510 };
4511
4512 static const GtkActionEntry attachment_popup_entries [] = {
4513         { "OpenAttachment", GTK_STOCK_OPEN, N_("_Open..."), NULL,
4514           NULL, G_CALLBACK (ev_attachment_popup_cmd_open_attachment) },
4515         { "SaveAttachmentAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), NULL,
4516           NULL, G_CALLBACK (ev_attachment_popup_cmd_save_attachment_as) },
4517 };
4518
4519 static void
4520 sidebar_links_link_activated_cb (EvSidebarLinks *sidebar_links, EvLink *link, EvWindow *window)
4521 {
4522         ev_view_handle_link (EV_VIEW (window->priv->view), link);
4523 }
4524
4525 static void
4526 activate_link_cb (EvPageAction *page_action, EvLink *link, EvWindow *window)
4527 {
4528         ev_view_handle_link (EV_VIEW (window->priv->view), link);
4529         gtk_widget_grab_focus (window->priv->view);
4530 }
4531
4532 static void
4533 navigation_action_activate_link_cb (EvNavigationAction *action, EvLink *link, EvWindow *window)
4534 {
4535         
4536         ev_view_handle_link (EV_VIEW (window->priv->view), link);
4537         gtk_widget_grab_focus (window->priv->view);
4538 }
4539
4540 static void
4541 register_custom_actions (EvWindow *window, GtkActionGroup *group)
4542 {
4543         GtkAction *action;
4544
4545         action = g_object_new (EV_TYPE_PAGE_ACTION,
4546                                "name", PAGE_SELECTOR_ACTION,
4547                                "label", _("Page"),
4548                                "tooltip", _("Select Page"),
4549                                "icon_name", "text-x-generic",
4550                                "visible_overflown", FALSE,
4551                                NULL);
4552         g_signal_connect (action, "activate_link",
4553                           G_CALLBACK (activate_link_cb), window);
4554         gtk_action_group_add_action (group, action);
4555         g_object_unref (action);
4556
4557         action = g_object_new (EPHY_TYPE_ZOOM_ACTION,
4558                                "name", ZOOM_CONTROL_ACTION,
4559                                "label", _("Zoom"),
4560                                "stock_id", EV_STOCK_ZOOM,
4561                                "tooltip", _("Adjust the zoom level"),
4562                                "zoom", 1.0,
4563                                NULL);
4564         g_signal_connect (action, "zoom_to_level",
4565                           G_CALLBACK (zoom_control_changed_cb), window);
4566         gtk_action_group_add_action (group, action);
4567         g_object_unref (action);
4568
4569         action = g_object_new (EV_TYPE_NAVIGATION_ACTION,
4570                                "name", NAVIGATION_ACTION,
4571                                "label", _("Navigation"),
4572                                "is_important", TRUE,
4573                                "short_label", _("Back"),
4574                                "stock_id", GTK_STOCK_GO_DOWN,
4575                                /*translators: this is the history action*/
4576                                "tooltip", _("Move across visited pages"),
4577                                NULL);
4578         g_signal_connect (action, "activate_link",
4579                           G_CALLBACK (navigation_action_activate_link_cb), window);
4580         gtk_action_group_add_action (group, action);
4581         g_object_unref (action);
4582
4583         action = g_object_new (EV_TYPE_OPEN_RECENT_ACTION,
4584                                "name", "FileOpenRecent",
4585                                "label", _("_Open..."),
4586                                "tooltip", _("Open an existing document"),
4587                                "stock_id", GTK_STOCK_OPEN,
4588                                NULL);
4589         g_signal_connect (action, "activate",
4590                           G_CALLBACK (ev_window_cmd_file_open), window);
4591         g_signal_connect (action, "item_activated",
4592                           G_CALLBACK (ev_window_open_recent_action_item_activated),
4593                           window);
4594         gtk_action_group_add_action (group, action);
4595         g_object_unref (action);
4596 }
4597
4598 static void
4599 set_action_properties (GtkActionGroup *action_group)
4600 {
4601         GtkAction *action;
4602
4603         action = gtk_action_group_get_action (action_group, "GoPreviousPage");
4604         g_object_set (action, "is-important", TRUE, NULL);
4605         /*translators: this is the label for toolbar button*/
4606         g_object_set (action, "short_label", _("Previous"), NULL);
4607
4608         action = gtk_action_group_get_action (action_group, "GoNextPage");
4609         g_object_set (action, "is-important", TRUE, NULL);
4610         /*translators: this is the label for toolbar button*/
4611         g_object_set (action, "short_label", _("Next"), NULL);
4612
4613         action = gtk_action_group_get_action (action_group, "ViewZoomIn");
4614         /*translators: this is the label for toolbar button*/
4615         g_object_set (action, "short_label", _("Zoom In"), NULL);
4616
4617         action = gtk_action_group_get_action (action_group, "ViewZoomOut");
4618         /*translators: this is the label for toolbar button*/
4619         g_object_set (action, "short_label", _("Zoom Out"), NULL);
4620
4621         action = gtk_action_group_get_action (action_group, "ViewBestFit");
4622         /*translators: this is the label for toolbar button*/
4623         g_object_set (action, "short_label", _("Best Fit"), NULL);
4624
4625         action = gtk_action_group_get_action (action_group, "ViewPageWidth");
4626         /*translators: this is the label for toolbar button*/
4627         g_object_set (action, "short_label", _("Fit Width"), NULL);
4628
4629         action = gtk_action_group_get_action (action_group, "LeaveFullscreen");
4630         g_object_set (action, "is-important", TRUE, NULL);
4631 }
4632
4633 static void
4634 set_chrome_actions (EvWindow *window)
4635 {
4636         EvWindowPrivate *priv = window->priv;
4637         GtkActionGroup *action_group = priv->action_group;
4638         GtkAction *action;
4639
4640         action= gtk_action_group_get_action (action_group, "ViewToolbar");
4641         g_signal_handlers_block_by_func
4642                 (action, G_CALLBACK (ev_window_view_toolbar_cb), window);
4643         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
4644                                       (priv->chrome & EV_CHROME_TOOLBAR) != 0);
4645         g_signal_handlers_unblock_by_func
4646                 (action, G_CALLBACK (ev_window_view_toolbar_cb), window);
4647 }
4648
4649 static void
4650 sidebar_widget_model_set (EvSidebarLinks *ev_sidebar_links,
4651                           GParamSpec     *pspec,
4652                           EvWindow       *ev_window)
4653 {
4654         GtkTreeModel *model;
4655         GtkAction *action;
4656
4657         g_object_get (G_OBJECT (ev_sidebar_links),
4658                       "model", &model,
4659                       NULL);
4660
4661         action = gtk_action_group_get_action (ev_window->priv->action_group, PAGE_SELECTOR_ACTION);
4662         ev_page_action_set_model (EV_PAGE_ACTION (action), model);
4663         g_object_unref (model);
4664 }
4665
4666 static gboolean
4667 view_actions_focus_in_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *window)
4668 {
4669 #ifdef ENABLE_DBUS
4670         GObject *keys;
4671
4672         keys = ev_application_get_media_keys (EV_APP);
4673         if (keys) {
4674                 ev_media_player_keys_focused (EV_MEDIA_PLAYER_KEYS (keys), window);
4675                 g_object_unref (keys);
4676         }
4677 #endif /* ENABLE_DBUS */
4678
4679         update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, FALSE);
4680         ev_window_set_action_sensitive (window, "ViewToolbar", TRUE);
4681
4682         ev_window_set_view_accels_sensitivity (window, TRUE);
4683
4684         update_chrome_visibility (window);
4685
4686         return FALSE;
4687 }
4688
4689 static gboolean
4690 view_actions_focus_out_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *window)
4691 {
4692         ev_window_set_view_accels_sensitivity (window, FALSE);
4693
4694         return FALSE;
4695 }
4696
4697 static void
4698 sidebar_page_main_widget_update_cb (GObject *ev_sidebar_page,
4699                                     GParamSpec         *pspec,
4700                                     EvWindow           *ev_window)
4701 {
4702         GtkWidget *widget;
4703         
4704         g_object_get (ev_sidebar_page, "main_widget", &widget, NULL);
4705
4706         if (widget != NULL) {           
4707                 g_signal_connect_object (widget, "focus_in_event",
4708                                          G_CALLBACK (view_actions_focus_in_cb),
4709                                          ev_window, 0);
4710                 g_signal_connect_object (widget, "focus_out_event",
4711                                          G_CALLBACK (view_actions_focus_out_cb),
4712                                          ev_window, 0);
4713                 g_object_unref (widget);
4714         }
4715 }
4716
4717 static gboolean
4718 window_state_event_cb (EvWindow *window, GdkEventWindowState *event, gpointer dummy)
4719 {
4720         if (!(event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
4721                 gboolean maximized;
4722
4723                 maximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED;
4724                 if (!ev_window_is_empty (window))
4725                         ev_metadata_manager_set_boolean (window->priv->uri, "window_maximized", maximized);
4726         }
4727
4728         return FALSE;
4729 }
4730
4731 static gboolean
4732 window_configure_event_cb (EvWindow *window, GdkEventConfigure *event, gpointer dummy)
4733 {
4734         char *uri = window->priv->uri;
4735         GdkWindowState state;
4736         int x, y, width, height, document_width, document_height;
4737
4738         state = gdk_window_get_state (GTK_WIDGET (window)->window);
4739
4740         if (!(state & GDK_WINDOW_STATE_FULLSCREEN)) {
4741                 gtk_window_get_position (GTK_WINDOW (window), &x, &y);
4742                 gtk_window_get_size (GTK_WINDOW (window), &width, &height);
4743
4744                 if (!ev_window_is_empty (window) && window->priv->page_cache) {
4745                         ev_page_cache_get_max_width (window->priv->page_cache, 
4746                                                      0, 1.0,
4747                                                      &document_width);
4748                         ev_page_cache_get_max_height (window->priv->page_cache, 
4749                                                       0, 1.0,
4750                                                       &document_height);                        
4751                         ev_metadata_manager_set_double (uri, "window_width_ratio", 
4752                                                         (double)width / document_width);
4753                         ev_metadata_manager_set_double (uri, "window_height_ratio", 
4754                                                         (double)height / document_height);
4755                         
4756                         ev_metadata_manager_set_int (uri, "window_x", x);
4757                         ev_metadata_manager_set_int (uri, "window_y", y);
4758                         ev_metadata_manager_set_int (uri, "window_width", width);
4759                         ev_metadata_manager_set_int (uri, "window_height", height);
4760                 }
4761         }
4762
4763         return FALSE;
4764 }
4765
4766 static void
4767 launch_action (EvWindow *window, EvLinkAction *action)
4768 {
4769         const char *filename = ev_link_action_get_filename (action);
4770         const char *content_type;
4771         GAppInfo *app_info;
4772         GFileInfo *file_info;
4773         GFile *file;
4774         GList *file_list = NULL;
4775         
4776         if (filename == NULL)
4777                 return;
4778
4779         if (g_path_is_absolute (filename)) {
4780                 file = g_file_new_for_path (filename);
4781         } else {
4782                 GFile *base_file;
4783                 
4784                 base_file = g_file_new_for_uri (window->priv->uri);
4785                 file = g_file_resolve_relative_path (base_file,
4786                                                      filename);
4787                 
4788                 g_object_unref (base_file);
4789         }
4790         
4791         file_info = g_file_query_info (file,
4792                                        G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
4793                                        0, NULL, NULL);
4794         if (file_info == NULL) {
4795                 g_object_unref (file);
4796                 return;
4797         }
4798         
4799         content_type = g_file_info_get_content_type (file_info);
4800         app_info = g_app_info_get_default_for_type (content_type, TRUE);
4801         
4802         file_list = g_list_append (file_list, file);
4803
4804         /* FIXME: should we use a GAppLaunchContext? */
4805         g_app_info_launch (app_info, file_list,
4806                            NULL, NULL);
4807         
4808         g_list_free (file_list);
4809         g_object_unref (app_info);
4810         g_object_unref (file_info);
4811         g_object_unref (file);
4812
4813         /* According to the PDF spec filename can be an executable. I'm not sure
4814            allowing to launch executables is a good idea though. -- marco */
4815 }
4816
4817 static void
4818 launch_external_uri (EvWindow *window, EvLinkAction *action)
4819 {
4820         const gchar *uri = ev_link_action_get_uri (action);
4821         GError *error = NULL;
4822         gboolean ret;
4823         
4824         ret = g_app_info_launch_default_for_uri (uri, NULL, &error);
4825         if (ret == FALSE) {
4826                 GtkWidget *dialog;
4827         
4828                 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
4829                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
4830                                                  GTK_MESSAGE_ERROR,
4831                                                  GTK_BUTTONS_CLOSE,
4832                                                  _("Unable to open external link"));
4833                 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
4834                                                           error->message, uri);
4835                 g_signal_connect (dialog, "response",
4836                                   G_CALLBACK (gtk_widget_destroy),
4837                                   NULL);
4838                 gtk_widget_show (dialog);
4839                 g_error_free(error);
4840         }
4841 }
4842
4843 static void
4844 open_remote_link (EvWindow *window, EvLinkAction *action)
4845 {
4846         gchar *uri;
4847         gchar *dir;
4848
4849         dir = g_path_get_dirname (window->priv->uri);
4850         
4851         uri = g_build_filename (dir, ev_link_action_get_filename (action),
4852                                 NULL);
4853         g_free (dir);
4854
4855         ev_application_open_uri_at_dest (EV_APP, uri,
4856                                          gtk_window_get_screen (GTK_WINDOW (window)),
4857                                          ev_link_action_get_dest (action),
4858                                          0,
4859                                          NULL, 
4860                                          FALSE,
4861                                          NULL,
4862                                          GDK_CURRENT_TIME);
4863
4864         g_free (uri);
4865 }
4866
4867 static void
4868 do_action_named (EvWindow *window, EvLinkAction *action)
4869 {
4870         const gchar *name = ev_link_action_get_name (action);
4871
4872         if (g_ascii_strcasecmp (name, "FirstPage") == 0) {
4873                 ev_window_cmd_go_first_page (NULL, window);
4874         } else if (g_ascii_strcasecmp (name, "PrevPage") == 0) {
4875                 ev_window_cmd_go_previous_page (NULL, window);
4876         } else if (g_ascii_strcasecmp (name, "NextPage") == 0) {
4877                 ev_window_cmd_go_next_page (NULL, window);
4878         } else if (g_ascii_strcasecmp (name, "LastPage") == 0) {
4879                 ev_window_cmd_go_last_page (NULL, window);
4880         } else if (g_ascii_strcasecmp (name, "GoToPage") == 0) {
4881                 ev_window_cmd_focus_page_selector (NULL, window);
4882         } else if (g_ascii_strcasecmp (name, "Find") == 0) {
4883                 ev_window_cmd_edit_find (NULL, window);
4884         } else if (g_ascii_strcasecmp (name, "Close") == 0) {
4885                 ev_window_cmd_file_close_window (NULL, window);
4886         } else {
4887                 g_warning ("Unimplemented named action: %s, please post a "
4888                            "bug report in Evince bugzilla "
4889                            "(http://bugzilla.gnome.org) with a testcase.",
4890                            name);
4891         }
4892 }
4893
4894 static void
4895 view_external_link_cb (EvView *view, EvLinkAction *action, EvWindow *window)
4896 {
4897         switch (ev_link_action_get_action_type (action)) {
4898                 case EV_LINK_ACTION_TYPE_GOTO_DEST: {
4899                         EvLinkDest *dest;
4900                         
4901                         dest = ev_link_action_get_dest (action);
4902                         if (!dest)
4903                                 return;
4904
4905                         ev_window_cmd_file_open_copy_at_dest (window, dest);
4906                 }
4907                         break;
4908                 case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
4909                         launch_external_uri (window, action);
4910                         break;
4911                 case EV_LINK_ACTION_TYPE_LAUNCH:
4912                         launch_action (window, action);
4913                         break;
4914                 case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
4915                         open_remote_link (window, action);
4916                         break;
4917                 case EV_LINK_ACTION_TYPE_NAMED:
4918                         do_action_named (window, action);
4919                         break;
4920                 default:
4921                         g_assert_not_reached ();
4922         }
4923 }
4924
4925 static void
4926 ev_view_popup_cmd_open_link (GtkAction *action, EvWindow *window)
4927 {
4928         ev_view_handle_link (EV_VIEW (window->priv->view), window->priv->link);
4929 }
4930
4931 static void
4932 ev_view_popup_cmd_open_link_new_window (GtkAction *action, EvWindow *window)
4933 {
4934         EvLinkAction *ev_action = NULL;
4935         EvLinkDest   *dest;
4936
4937         ev_action = ev_link_get_action (window->priv->link);
4938         if (!ev_action)
4939                 return;
4940
4941         dest = ev_link_action_get_dest (ev_action);
4942         if (!dest)
4943                 return;
4944
4945         ev_window_cmd_file_open_copy_at_dest (window, dest);
4946 }
4947
4948 static void
4949 ev_view_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window)
4950 {
4951         EvLinkAction *ev_action;
4952
4953         ev_action = ev_link_get_action (window->priv->link);
4954         if (!ev_action)
4955                 return;
4956
4957         ev_view_copy_link_address (EV_VIEW (window->priv->view),
4958                                    ev_action);
4959 }
4960
4961
4962 static void
4963 image_save_dialog_response_cb (GtkWidget *fc,
4964                                gint       response_id,
4965                                EvWindow  *ev_window)
4966 {
4967         GFile           *target_file;
4968         gboolean         is_native;
4969         GError          *error = NULL;
4970         GdkPixbuf       *pixbuf;
4971         gchar           *uri;
4972         gchar          **extensions;
4973         gchar           *filename;
4974         gchar           *file_format;
4975         GdkPixbufFormat *format;
4976         GtkFileFilter   *filter;
4977         
4978         if (response_id != GTK_RESPONSE_OK) {
4979                 gtk_widget_destroy (fc);
4980                 return;
4981         }
4982
4983         uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
4984         filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (fc));
4985         format = g_object_get_data (G_OBJECT (filter), "pixbuf-format");
4986         
4987         if (format == NULL) {
4988                 format = get_gdk_pixbuf_format_by_extension (uri);
4989         }
4990
4991         if (format == NULL) {
4992                 ev_window_error_message (GTK_WINDOW (ev_window),
4993                                          _("Couldn't find appropriate format to save image"),
4994                                          NULL);
4995                 g_free (uri);
4996                 gtk_widget_destroy (fc);
4997
4998                 return;
4999         }
5000
5001         extensions = gdk_pixbuf_format_get_extensions (format);
5002         if (g_str_has_suffix(uri, extensions[0])) {
5003                 gchar *uri_extension;
5004                 
5005                 uri_extension = g_strconcat (uri, ".", extensions[0], NULL);
5006                 target_file = g_file_new_for_uri (uri_extension);
5007                 g_free (uri_extension);
5008         } else {
5009                 target_file = g_file_new_for_uri (uri);
5010         }
5011         g_strfreev(extensions);
5012         g_free (uri);
5013         
5014         is_native = g_file_is_native (target_file);
5015         if (is_native) {
5016                 filename = g_file_get_path (target_file);
5017         } else {
5018                 filename = ev_tmp_filename ("saveimage");
5019         }
5020
5021         ev_document_doc_mutex_lock ();
5022         pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (ev_window->priv->document),
5023                                                ev_window->priv->image);
5024         ev_document_doc_mutex_unlock ();
5025
5026         file_format = gdk_pixbuf_format_get_name (format);
5027         gdk_pixbuf_save (pixbuf, filename, file_format, &error, NULL);
5028         g_free (file_format);
5029         g_object_unref (pixbuf);
5030         
5031         if (error) {
5032                 ev_window_error_message (GTK_WINDOW (ev_window),
5033                                          _("The image could not be saved."),
5034                                          error);
5035                 g_error_free (error);
5036                 g_free (filename);
5037                 g_object_unref (target_file);
5038                 gtk_widget_destroy (fc);
5039
5040                 return;
5041         }
5042
5043         if (!is_native) {
5044                 GFile *source_file;
5045                 
5046                 source_file = g_file_new_for_uri (filename);
5047                 
5048                 ev_window_save_remote (ev_window, source_file, target_file);
5049                 g_object_unref (source_file);
5050         }
5051         
5052         g_free (filename);
5053         g_object_unref (target_file);
5054         gtk_widget_destroy (fc);
5055 }
5056
5057 static void
5058 ev_view_popup_cmd_save_image_as (GtkAction *action, EvWindow *window)
5059 {
5060         GtkWidget *fc;
5061
5062         if (!window->priv->image)
5063                 return;
5064
5065         fc = gtk_file_chooser_dialog_new (_("Save Image"),
5066                                           GTK_WINDOW (window),
5067                                           GTK_FILE_CHOOSER_ACTION_SAVE,
5068                                           GTK_STOCK_CANCEL,
5069                                           GTK_RESPONSE_CANCEL,
5070                                           GTK_STOCK_SAVE, GTK_RESPONSE_OK,
5071                                           NULL);
5072
5073         gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK);
5074         gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (fc), FALSE);
5075         gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE);
5076         
5077         file_chooser_dialog_add_writable_pixbuf_formats (GTK_FILE_CHOOSER (fc));
5078         
5079         g_signal_connect (fc, "response",
5080                           G_CALLBACK (image_save_dialog_response_cb),
5081                           window);
5082
5083         gtk_widget_show (fc);
5084 }
5085
5086 static void
5087 ev_view_popup_cmd_copy_image (GtkAction *action, EvWindow *window)
5088 {
5089         GtkClipboard *clipboard;
5090         GdkPixbuf    *pixbuf;
5091
5092         if (!window->priv->image)
5093                 return;
5094         
5095         clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window),
5096                                               GDK_SELECTION_CLIPBOARD);
5097         ev_document_doc_mutex_lock ();
5098         pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (window->priv->document),
5099                                                window->priv->image);
5100         ev_document_doc_mutex_unlock ();
5101         
5102         gtk_clipboard_set_image (clipboard, pixbuf);
5103         g_object_unref (pixbuf);
5104 }
5105
5106 static void
5107 ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window)
5108 {
5109         GList *l;
5110         
5111         if (!window->priv->attach_list)
5112                 return;
5113
5114         for (l = window->priv->attach_list; l && l->data; l = g_list_next (l)) {
5115                 EvAttachment *attachment;
5116                 GError       *error = NULL;
5117                 
5118                 attachment = (EvAttachment *) l->data;
5119                 
5120                 ev_attachment_open (attachment, &error);
5121
5122                 if (error) {
5123                         ev_window_error_message (GTK_WINDOW (window),
5124                                                  _("Unable to open attachment"),
5125                                                  error);
5126                         g_error_free (error);
5127                 }
5128         }
5129 }
5130
5131 static void
5132 attachment_save_dialog_response_cb (GtkWidget *fc,
5133                                     gint       response_id,
5134                                     EvWindow  *ev_window)
5135 {
5136         GFile                *target_file;
5137         gchar                *uri;
5138         GList                *l;
5139         GtkFileChooserAction  fc_action;
5140         gboolean              is_dir;
5141         gboolean              is_native;
5142         
5143         if (response_id != GTK_RESPONSE_OK) {
5144                 gtk_widget_destroy (fc);
5145                 return;
5146         }
5147
5148         uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
5149         target_file = g_file_new_for_uri (uri);
5150         g_object_get (G_OBJECT (fc), "action", &fc_action, NULL);
5151         is_dir = (fc_action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
5152         is_native = g_file_is_native (target_file);
5153         
5154         for (l = ev_window->priv->attach_list; l && l->data; l = g_list_next (l)) {
5155                 EvAttachment *attachment;
5156                 GFile        *save_to;
5157                 GError       *error = NULL;
5158                 
5159                 attachment = (EvAttachment *) l->data;
5160
5161                 if (is_native) {
5162                         if (is_dir) {
5163                                 save_to = g_file_get_child (target_file,
5164                                                             ev_attachment_get_name (attachment));
5165                         } else {
5166                                 save_to = g_object_ref (target_file);
5167                         }
5168                 } else {
5169                         save_to = ev_tmp_file_get ("saveattachment");
5170                 }
5171
5172                 ev_attachment_save (attachment, save_to, &error);
5173                 
5174                 if (error) {
5175                         ev_window_error_message (GTK_WINDOW (ev_window),
5176                                                  _("The attachment could not be saved."),
5177                                                  error);
5178                         g_error_free (error);
5179                         g_object_unref (save_to);
5180
5181                         continue;
5182                 }
5183
5184                 if (!is_native) {
5185                         GFile *dest_file;
5186
5187                         if (is_dir) {
5188                                 dest_file = g_file_get_child (target_file,
5189                                                               ev_attachment_get_name (attachment));
5190                         } else {
5191                                 dest_file = g_object_ref (target_file);
5192                         }
5193
5194                         ev_window_save_remote (ev_window, save_to, dest_file);
5195
5196                         g_object_unref (dest_file);
5197                 }
5198
5199                 g_object_unref (save_to);
5200         }
5201
5202         g_free (uri);
5203         g_object_unref (target_file);
5204
5205         gtk_widget_destroy (fc);
5206 }
5207
5208 static void
5209 ev_attachment_popup_cmd_save_attachment_as (GtkAction *action, EvWindow *window)
5210 {
5211         GtkWidget    *fc;
5212         EvAttachment *attachment = NULL;
5213
5214         if (!window->priv->attach_list)
5215                 return;
5216
5217         if (g_list_length (window->priv->attach_list) == 1)
5218                 attachment = (EvAttachment *) window->priv->attach_list->data;
5219         
5220         fc = gtk_file_chooser_dialog_new (
5221                 _("Save Attachment"),
5222                 GTK_WINDOW (window),
5223                 attachment ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
5224                 GTK_STOCK_CANCEL,
5225                 GTK_RESPONSE_CANCEL,
5226                 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
5227                 NULL);
5228
5229         gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK);
5230         gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE);
5231         gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (fc), FALSE);
5232
5233         if (attachment)
5234                 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (fc),
5235                                                    ev_attachment_get_name (attachment));
5236
5237         g_signal_connect (fc, "response",
5238                           G_CALLBACK (attachment_save_dialog_response_cb),
5239                           window);
5240
5241         gtk_widget_show (fc);
5242 }
5243
5244 static void
5245 ev_window_init (EvWindow *ev_window)
5246 {
5247         GtkActionGroup *action_group;
5248         GtkAccelGroup *accel_group;
5249         GError *error = NULL;
5250         GtkWidget *sidebar_widget;
5251
5252         g_signal_connect (ev_window, "configure_event",
5253                           G_CALLBACK (window_configure_event_cb), NULL);
5254         g_signal_connect (ev_window, "window_state_event",
5255                           G_CALLBACK (window_state_event_cb), NULL);
5256
5257         ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window);
5258
5259         ev_window->priv->page_mode = PAGE_MODE_DOCUMENT;
5260         ev_window->priv->title = ev_window_title_new (ev_window);
5261
5262         ev_window->priv->main_box = gtk_vbox_new (FALSE, 0);
5263         gtk_container_add (GTK_CONTAINER (ev_window), ev_window->priv->main_box);
5264         gtk_widget_show (ev_window->priv->main_box);
5265
5266         action_group = gtk_action_group_new ("MenuActions");
5267         ev_window->priv->action_group = action_group;
5268         gtk_action_group_set_translation_domain (action_group, NULL);
5269         gtk_action_group_add_actions (action_group, entries,
5270                                       G_N_ELEMENTS (entries), ev_window);
5271         gtk_action_group_add_toggle_actions (action_group, toggle_entries,
5272                                              G_N_ELEMENTS (toggle_entries),
5273                                              ev_window);
5274         set_action_properties (action_group);
5275         register_custom_actions (ev_window, action_group);
5276
5277         ev_window->priv->ui_manager = gtk_ui_manager_new ();
5278         gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
5279                                             action_group, 0);
5280
5281         accel_group =
5282                 gtk_ui_manager_get_accel_group (ev_window->priv->ui_manager);
5283         gtk_window_add_accel_group (GTK_WINDOW (ev_window), accel_group);
5284
5285         ev_window_set_view_accels_sensitivity (ev_window, FALSE);
5286
5287         action_group = gtk_action_group_new ("ViewPopupActions");
5288         ev_window->priv->view_popup_action_group = action_group;
5289         gtk_action_group_set_translation_domain (action_group, NULL);
5290         gtk_action_group_add_actions (action_group, view_popup_entries,
5291                                       G_N_ELEMENTS (view_popup_entries),
5292                                       ev_window);
5293         gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
5294                                             action_group, 0);
5295
5296         action_group = gtk_action_group_new ("AttachmentPopupActions");
5297         ev_window->priv->attachment_popup_action_group = action_group;
5298         gtk_action_group_set_translation_domain (action_group, NULL);
5299         gtk_action_group_add_actions (action_group, attachment_popup_entries,
5300                                       G_N_ELEMENTS (attachment_popup_entries),
5301                                       ev_window);
5302         gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
5303                                             action_group, 0);
5304
5305         if (!gtk_ui_manager_add_ui_from_file (ev_window->priv->ui_manager,
5306                                               DATADIR"/evince-ui.xml",
5307                                               &error)) {
5308                 g_warning ("building menus failed: %s", error->message);
5309                 g_error_free (error);
5310         }
5311         
5312 #if GTK_CHECK_VERSION(2,11,4)
5313         ev_window->priv->recent_manager = gtk_recent_manager_get_default ();
5314 #else
5315         /* It's fine to just use the one of the default screen here */
5316         ev_window->priv->recent_manager = gtk_recent_manager_get_for_screen (
5317                 gdk_screen_get_default ());
5318 #endif
5319         ev_window->priv->recent_action_group = NULL;
5320         ev_window->priv->recent_ui_id = 0;
5321         g_signal_connect_swapped (ev_window->priv->recent_manager,
5322                                   "changed",
5323                                   G_CALLBACK (ev_window_setup_recent),
5324                                   ev_window);
5325
5326         ev_window->priv->menubar =
5327                  gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
5328                                             "/MainMenu");
5329         gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box),
5330                             ev_window->priv->menubar,
5331                             FALSE, FALSE, 0);
5332
5333         ev_window->priv->toolbar = GTK_WIDGET 
5334           (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR,
5335                          "ui-manager", ev_window->priv->ui_manager,
5336                          "popup-path", "/ToolbarPopup",
5337                          "model", ev_application_get_toolbars_model (EV_APP),
5338                          NULL));
5339
5340         egg_editable_toolbar_show (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar),
5341                                    "DefaultToolBar");
5342         gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box),
5343                             ev_window->priv->toolbar,
5344                             FALSE, FALSE, 0);
5345         gtk_widget_show (ev_window->priv->toolbar);
5346
5347         /* Add the main area */
5348         ev_window->priv->hpaned = gtk_hpaned_new ();
5349         g_signal_connect (ev_window->priv->hpaned,
5350                           "notify::position",
5351                           G_CALLBACK (ev_window_sidebar_position_change_cb),
5352                           ev_window);
5353         
5354         gtk_paned_set_position (GTK_PANED (ev_window->priv->hpaned), SIDEBAR_DEFAULT_SIZE);
5355         gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box), ev_window->priv->hpaned,
5356                             TRUE, TRUE, 0);
5357         gtk_widget_show (ev_window->priv->hpaned);
5358         
5359         ev_window->priv->sidebar = ev_sidebar_new ();
5360         gtk_paned_pack1 (GTK_PANED (ev_window->priv->hpaned),
5361                          ev_window->priv->sidebar, FALSE, FALSE);
5362         gtk_widget_show (ev_window->priv->sidebar);
5363
5364         /* Stub sidebar, for now */
5365
5366         sidebar_widget = ev_sidebar_thumbnails_new ();
5367         ev_window->priv->sidebar_thumbs = sidebar_widget;
5368         g_signal_connect (sidebar_widget,
5369                           "notify::main-widget",
5370                           G_CALLBACK (sidebar_page_main_widget_update_cb),
5371                           ev_window);
5372         sidebar_page_main_widget_update_cb (G_OBJECT (sidebar_widget), NULL, ev_window);
5373         gtk_widget_show (sidebar_widget);
5374         ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
5375                              sidebar_widget);
5376
5377         sidebar_widget = ev_sidebar_links_new ();
5378         ev_window->priv->sidebar_links = sidebar_widget;
5379         g_signal_connect (sidebar_widget,
5380                           "notify::model",
5381                           G_CALLBACK (sidebar_widget_model_set),
5382                           ev_window);
5383         g_signal_connect (sidebar_widget,
5384                           "link_activated",
5385                           G_CALLBACK (sidebar_links_link_activated_cb),
5386                           ev_window);
5387         sidebar_page_main_widget_update_cb (G_OBJECT (sidebar_widget), NULL, ev_window);
5388         gtk_widget_show (sidebar_widget);
5389         ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
5390                              sidebar_widget);
5391
5392         sidebar_widget = ev_sidebar_attachments_new ();
5393         ev_window->priv->sidebar_attachments = sidebar_widget;
5394         g_signal_connect_object (sidebar_widget,
5395                                  "popup",
5396                                  G_CALLBACK (attachment_bar_menu_popup_cb),
5397                                  ev_window, 0);
5398         gtk_widget_show (sidebar_widget);
5399         ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
5400                              sidebar_widget);
5401
5402         ev_window->priv->view_box = gtk_vbox_new (FALSE, 0);
5403         ev_window->priv->scrolled_window =
5404                 GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW,
5405                                           "shadow-type", GTK_SHADOW_IN,
5406                                           NULL));
5407         gtk_box_pack_start (GTK_BOX (ev_window->priv->view_box),
5408                             ev_window->priv->scrolled_window,
5409                             TRUE, TRUE, 0);
5410         gtk_widget_show (ev_window->priv->scrolled_window);
5411
5412         gtk_paned_add2 (GTK_PANED (ev_window->priv->hpaned),
5413                         ev_window->priv->view_box);
5414         gtk_widget_show (ev_window->priv->view_box);
5415
5416         ev_window->priv->view = ev_view_new ();
5417         ev_view_set_screen_dpi (EV_VIEW (ev_window->priv->view),
5418                                 get_screen_dpi (GTK_WINDOW (ev_window)));
5419         ev_window->priv->password_view = ev_password_view_new ();
5420         g_signal_connect_swapped (ev_window->priv->password_view,
5421                                   "unlock",
5422                                   G_CALLBACK (ev_window_popup_password_dialog),
5423                                   ev_window);
5424         g_signal_connect_object (ev_window->priv->view, "focus_in_event",
5425                                  G_CALLBACK (view_actions_focus_in_cb),
5426                                  ev_window, 0);
5427         g_signal_connect_object (ev_window->priv->view, "focus_out_event",
5428                                  G_CALLBACK (view_actions_focus_out_cb),
5429                                  ev_window, 0);
5430         g_signal_connect_object (ev_window->priv->view, "external-link",
5431                                  G_CALLBACK (view_external_link_cb),
5432                                  ev_window, 0);
5433         g_signal_connect_object (ev_window->priv->view, "handle-link",
5434                                  G_CALLBACK (view_handle_link_cb),
5435                                  ev_window, 0);
5436
5437         g_signal_connect_object (ev_window->priv->view,
5438                                  "popup",
5439                                  G_CALLBACK (view_menu_popup_cb),
5440                                  ev_window, 0);
5441         gtk_widget_show (ev_window->priv->view);
5442         gtk_widget_show (ev_window->priv->password_view);
5443
5444         /* Find Bar */
5445         ev_window->priv->find_bar = egg_find_bar_new ();
5446         gtk_box_pack_end (GTK_BOX (ev_window->priv->main_box),
5447                           ev_window->priv->find_bar,
5448                           FALSE, TRUE, 0);
5449
5450         /* We own a ref on these widgets, as we can swap them in and out */
5451         g_object_ref (ev_window->priv->view);
5452         g_object_ref (ev_window->priv->password_view);
5453
5454         gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window),
5455                            ev_window->priv->view);
5456
5457         g_signal_connect (ev_window->priv->view,
5458                           "notify::find-status",
5459                           G_CALLBACK (view_find_status_changed_cb),
5460                           ev_window);
5461         g_signal_connect (ev_window->priv->view,
5462                           "notify::sizing-mode",
5463                           G_CALLBACK (ev_window_sizing_mode_changed_cb),
5464                           ev_window);
5465         g_signal_connect (ev_window->priv->view,
5466                           "notify::zoom",
5467                           G_CALLBACK (ev_window_zoom_changed_cb),
5468                           ev_window);
5469         g_signal_connect (ev_window->priv->view,
5470                           "notify::dual-page",
5471                           G_CALLBACK (ev_window_dual_mode_changed_cb),
5472                           ev_window);
5473         g_signal_connect (ev_window->priv->view,
5474                           "notify::continuous",
5475                           G_CALLBACK (ev_window_continuous_changed_cb),
5476                           ev_window);
5477         g_signal_connect (ev_window->priv->view,
5478                           "notify::rotation",
5479                           G_CALLBACK (ev_window_rotation_changed_cb),
5480                           ev_window);
5481         g_signal_connect (ev_window->priv->view,
5482                           "notify::has-selection",
5483                           G_CALLBACK (ev_window_has_selection_changed_cb),
5484                           ev_window);
5485
5486         /* Connect sidebar signals */
5487         g_signal_connect (ev_window->priv->sidebar,
5488                           "notify::visible",
5489                           G_CALLBACK (ev_window_sidebar_visibility_changed_cb),
5490                           ev_window);
5491         g_signal_connect (ev_window->priv->sidebar,
5492                           "notify::current-page",
5493                           G_CALLBACK (ev_window_sidebar_current_page_changed_cb),
5494                           ev_window);
5495
5496         /* Connect to find bar signals */
5497         g_signal_connect (ev_window->priv->find_bar,
5498                           "previous",
5499                           G_CALLBACK (find_bar_previous_cb),
5500                           ev_window);
5501         g_signal_connect (ev_window->priv->find_bar,
5502                           "next",
5503                           G_CALLBACK (find_bar_next_cb),
5504                           ev_window);
5505         g_signal_connect (ev_window->priv->find_bar,
5506                           "close",
5507                           G_CALLBACK (find_bar_close_cb),
5508                           ev_window);
5509         g_signal_connect (ev_window->priv->find_bar,
5510                           "notify::search-string",
5511                           G_CALLBACK (find_bar_search_changed_cb),
5512                           ev_window);
5513         g_signal_connect (ev_window->priv->find_bar,
5514                           "notify::case-sensitive",
5515                           G_CALLBACK (find_bar_search_changed_cb),
5516                           ev_window);
5517         g_signal_connect (ev_window->priv->find_bar,
5518                           "notify::visible",
5519                           G_CALLBACK (find_bar_visibility_changed_cb),
5520                           ev_window);
5521         g_signal_connect (ev_window->priv->find_bar,
5522                           "scroll",
5523                           G_CALLBACK (find_bar_scroll),
5524                           ev_window);
5525
5526         /* Popups */
5527         ev_window->priv->view_popup = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
5528                                                                  "/DocumentPopup");
5529         ev_window->priv->link = NULL;
5530
5531         ev_window->priv->attachment_popup = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
5532                                                                        "/AttachmentPopup");
5533         ev_window->priv->attach_list = NULL;
5534
5535         /* Give focus to the document view */
5536         gtk_widget_grab_focus (ev_window->priv->view);
5537
5538         /* Set it user interface params */
5539         ev_window_setup_recent (ev_window);
5540
5541         setup_chrome_from_metadata (ev_window);
5542         set_chrome_actions (ev_window);
5543         update_chrome_visibility (ev_window);
5544
5545         gtk_window_set_default_size (GTK_WINDOW (ev_window), 600, 600);
5546
5547         setup_view_from_metadata (ev_window);
5548         setup_sidebar_from_metadata (ev_window, NULL);
5549
5550         ev_window_sizing_mode_changed_cb (EV_VIEW (ev_window->priv->view), NULL, ev_window);
5551         ev_window_setup_action_sensitivity (ev_window);
5552 }
5553
5554 /**
5555  * ev_window_new:
5556  *
5557  * Creates a #GtkWidget that represents the window.
5558  *
5559  * Returns: the #GtkWidget that represents the window.
5560  */
5561 GtkWidget *
5562 ev_window_new (void)
5563 {
5564         GtkWidget *ev_window;
5565
5566         ev_window = GTK_WIDGET (g_object_new (EV_TYPE_WINDOW,
5567                                               "type", GTK_WINDOW_TOPLEVEL,
5568                                               NULL));
5569
5570         return ev_window;
5571 }