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
4 * Copyright (C) 2009 Juanjo Marín <juanj.marin@juntadeandalucia.es>
5 * Copyright (C) 2008 Carlos Garcia Campos
6 * Copyright (C) 2004 Martin Kretzschmar
7 * Copyright (C) 2004 Red Hat, Inc.
8 * Copyright (C) 2000, 2001, 2002, 2003, 2004 Marco Pesenti Gritti
9 * Copyright © 2003, 2004, 2005, 2009 Christian Persch
12 * Martin Kretzschmar <martink@gnome.org>
14 * Evince is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * Evince is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
39 #include <glib/gstdio.h>
40 #include <glib/gi18n.h>
44 #include "egg-editable-toolbar.h"
45 #include "egg-toolbar-editor.h"
46 #include "egg-toolbars-model.h"
48 #include "eggfindbar.h"
50 #include "ephy-zoom-action.h"
51 #include "ephy-zoom.h"
53 #include "ev-application.h"
54 #include "ev-document-factory.h"
55 #include "ev-document-find.h"
56 #include "ev-document-fonts.h"
57 #include "ev-document-images.h"
58 #include "ev-document-links.h"
59 #include "ev-document-annotations.h"
60 #include "ev-document-type-builtins.h"
61 #include "ev-document-misc.h"
62 #include "ev-file-exporter.h"
63 #include "ev-file-helpers.h"
64 #include "ev-file-monitor.h"
65 #include "ev-history.h"
67 #include "ev-job-scheduler.h"
69 #include "ev-message-area.h"
70 #include "ev-metadata.h"
71 #include "ev-navigation-action.h"
72 #include "ev-open-recent-action.h"
73 #include "ev-page-action.h"
74 #include "ev-password-view.h"
75 #include "ev-properties-dialog.h"
76 #include "ev-sidebar-annotations.h"
77 #include "ev-sidebar-attachments.h"
78 #include "ev-sidebar.h"
79 #include "ev-sidebar-links.h"
80 #include "ev-sidebar-page.h"
81 #include "ev-sidebar-thumbnails.h"
82 #include "ev-sidebar-layers.h"
83 #include "ev-stock-icons.h"
85 #include "ev-keyring.h"
87 #include "ev-view-presentation.h"
88 #include "ev-view-type-builtins.h"
89 #include "ev-window.h"
90 #include "ev-window-title.h"
91 #include "ev-print-operation.h"
92 #include "ev-progress-message-area.h"
93 #include "ev-annotation-properties-dialog.h"
94 #include "ev-bookmarks.h"
95 #include "ev-bookmark-action.h"
98 #include "ev-media-player-keys.h"
99 #endif /* ENABLE_DBUS */
107 EV_CHROME_MENUBAR = 1 << 0,
108 EV_CHROME_TOOLBAR = 1 << 1,
109 EV_CHROME_FINDBAR = 1 << 2,
110 EV_CHROME_RAISE_TOOLBAR = 1 << 3,
111 EV_CHROME_FULLSCREEN_TOOLBAR = 1 << 4,
112 EV_CHROME_SIDEBAR = 1 << 5,
113 EV_CHROME_NORMAL = EV_CHROME_MENUBAR | EV_CHROME_TOOLBAR | EV_CHROME_SIDEBAR
122 struct _EvWindowPrivate {
133 GtkWidget *scrolled_window;
135 GtkWidget *presentation_view;
136 GtkWidget *message_area;
137 GtkWidget *password_view;
138 GtkWidget *sidebar_thumbs;
139 GtkWidget *sidebar_links;
140 GtkWidget *sidebar_attachments;
141 GtkWidget *sidebar_layers;
142 GtkWidget *sidebar_annots;
146 GSettings *default_settings;
147 GSettings *lockdown_settings;
150 guint menubar_accel_keyval;
151 GdkModifierType menubar_accel_modifier;
153 /* Progress Messages */
155 GCancellable *progress_cancellable;
158 GtkWidget *properties;
159 GtkWidget *print_dialog;
162 GtkActionGroup *action_group;
163 GtkActionGroup *view_popup_action_group;
164 GtkActionGroup *attachment_popup_action_group;
165 GtkRecentManager *recent_manager;
166 GtkActionGroup *recent_action_group;
168 GtkActionGroup *bookmarks_action_group;
169 guint bookmarks_ui_id;
170 GtkUIManager *ui_manager;
172 /* Fullscreen mode */
173 GtkWidget *fullscreen_toolbar;
176 GtkWidget *view_popup;
181 /* Popup attachment */
182 GtkWidget *attachment_popup;
186 EvDocumentModel *model;
191 EvFileMonitor *monitor;
192 guint setup_document_idle;
194 EvDocument *document;
196 EvWindowPageMode page_mode;
197 EvWindowTitle *title;
198 EvMetadata *metadata;
199 EvBookmarks *bookmarks;
204 gchar *search_string;
205 EvWindowRunMode window_mode;
209 EvJob *thumbnail_job;
215 GtkPrintSettings *print_settings;
216 GtkPageSetup *print_page_setup;
217 gboolean close_after_print;
221 guint dbus_object_id;
222 gchar *dbus_object_path;
226 #define EV_WINDOW_GET_PRIVATE(object) \
227 (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_WINDOW, EvWindowPrivate))
229 #define EV_WINDOW_IS_PRESENTATION(w) (w->priv->presentation_view != NULL)
231 #define PAGE_SELECTOR_ACTION "PageSelector"
232 #define ZOOM_CONTROL_ACTION "ViewZoom"
233 #define NAVIGATION_ACTION "Navigation"
235 #define GS_LOCKDOWN_SCHEMA_NAME "org.gnome.desktop.lockdown"
236 #define GS_LOCKDOWN_SAVE "disable-save-to-disk"
237 #define GS_LOCKDOWN_PRINT "disable-printing"
238 #define GS_LOCKDOWN_PRINT_SETUP "disable-print-setup"
241 #define EV_WINDOW_DBUS_OBJECT_PATH "/org/gnome/evince/Window/%d"
242 #define EV_WINDOW_DBUS_INTERFACE "org.gnome.evince.Window"
245 #define GS_SCHEMA_NAME "org.gnome.Evince"
246 #define GS_OVERRIDE_RESTRICTIONS "override-restrictions"
248 #define SIDEBAR_DEFAULT_SIZE 132
249 #define LINKS_SIDEBAR_ID "links"
250 #define THUMBNAILS_SIDEBAR_ID "thumbnails"
251 #define ATTACHMENTS_SIDEBAR_ID "attachments"
252 #define LAYERS_SIDEBAR_ID "layers"
253 #define ANNOTS_SIDEBAR_ID "annotations"
255 #define EV_PRINT_SETTINGS_FILE "print-settings"
256 #define EV_PRINT_SETTINGS_GROUP "Print Settings"
257 #define EV_PAGE_SETUP_GROUP "Page Setup"
259 #define EV_TOOLBARS_FILENAME "evince-toolbar.xml"
261 #define MIN_SCALE 0.05409
262 #define PAGE_CACHE_SIZE 52428800 /* 50MB */
264 #define MAX_RECENT_ITEM_LEN (40)
266 static const gchar *document_print_settings[] = {
267 GTK_PRINT_SETTINGS_N_COPIES,
268 GTK_PRINT_SETTINGS_COLLATE,
269 GTK_PRINT_SETTINGS_REVERSE,
270 GTK_PRINT_SETTINGS_NUMBER_UP,
271 GTK_PRINT_SETTINGS_SCALE,
272 GTK_PRINT_SETTINGS_PRINT_PAGES,
273 GTK_PRINT_SETTINGS_PAGE_RANGES,
274 GTK_PRINT_SETTINGS_PAGE_SET,
275 GTK_PRINT_SETTINGS_OUTPUT_URI
278 static void ev_window_update_actions (EvWindow *ev_window);
279 static void ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar,
281 EvWindow *ev_window);
282 static void ev_window_view_toolbar_cb (GtkAction *action,
283 EvWindow *ev_window);
284 static void ev_window_set_page_mode (EvWindow *window,
285 EvWindowPageMode page_mode);
286 static void ev_window_load_job_cb (EvJob *job,
288 static void ev_window_reload_document (EvWindow *window,
290 static void ev_window_reload_job_cb (EvJob *job,
292 static void ev_window_set_icon_from_thumbnail (EvJobThumbnail *job,
293 EvWindow *ev_window);
294 static void ev_window_save_job_cb (EvJob *save,
296 static void ev_window_sizing_mode_changed_cb (EvDocumentModel *model,
298 EvWindow *ev_window);
299 static void ev_window_zoom_changed_cb (EvDocumentModel *model,
301 EvWindow *ev_window);
302 static void ev_window_add_recent (EvWindow *window,
303 const char *filename);
304 static void ev_window_run_fullscreen (EvWindow *window);
305 static void ev_window_stop_fullscreen (EvWindow *window,
306 gboolean unfullscreen_window);
307 static void ev_window_cmd_view_fullscreen (GtkAction *action,
309 static void ev_window_run_presentation (EvWindow *window);
310 static void ev_window_stop_presentation (EvWindow *window,
311 gboolean unfullscreen_window);
312 static void ev_window_cmd_view_presentation (GtkAction *action,
314 static void ev_view_popup_cmd_open_link (GtkAction *action,
316 static void ev_view_popup_cmd_open_link_new_window (GtkAction *action,
318 static void ev_view_popup_cmd_copy_link_address (GtkAction *action,
320 static void ev_view_popup_cmd_save_image_as (GtkAction *action,
322 static void ev_view_popup_cmd_copy_image (GtkAction *action,
324 static void ev_view_popup_cmd_annot_properties (GtkAction *action,
326 static void ev_attachment_popup_cmd_open_attachment (GtkAction *action,
328 static void ev_attachment_popup_cmd_save_attachment_as (GtkAction *action,
330 static void ev_window_cmd_view_best_fit (GtkAction *action,
331 EvWindow *ev_window);
332 static void ev_window_cmd_view_page_width (GtkAction *action,
333 EvWindow *ev_window);
334 static void view_handle_link_cb (EvView *view,
337 static void ev_window_update_find_status_message (EvWindow *ev_window);
338 static void ev_window_cmd_edit_find (GtkAction *action,
339 EvWindow *ev_window);
340 static void find_bar_search_changed_cb (EggFindBar *find_bar,
342 EvWindow *ev_window);
343 static void ev_window_load_file_remote (EvWindow *ev_window,
345 static void ev_window_media_player_key_pressed (EvWindow *window,
348 static void ev_window_update_max_min_scale (EvWindow *window);
350 static void ev_window_emit_closed (EvWindow *window);
351 static void ev_window_emit_doc_loaded (EvWindow *window);
353 static void ev_window_setup_bookmarks (EvWindow *window);
355 static guint ev_window_n_copies = 0;
357 G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)
360 get_screen_dpi (EvWindow *window)
364 screen = gtk_window_get_screen (GTK_WINDOW (window));
365 return ev_document_misc_get_screen_dpi (screen);
369 ev_window_set_action_sensitive (EvWindow *ev_window,
373 GtkAction *action = gtk_action_group_get_action (ev_window->priv->action_group,
375 gtk_action_set_sensitive (action, sensitive);
380 ev_window_setup_action_sensitivity (EvWindow *ev_window)
382 EvDocument *document = ev_window->priv->document;
383 const EvDocumentInfo *info = NULL;
384 gboolean has_document = FALSE;
385 gboolean ok_to_print = TRUE;
386 gboolean ok_to_copy = TRUE;
387 gboolean has_properties = TRUE;
388 gboolean override_restrictions = TRUE;
389 gboolean can_get_text = FALSE;
390 gboolean has_pages = FALSE;
391 gboolean can_find = FALSE;
395 has_pages = ev_document_get_n_pages (document) > 0;
396 info = ev_document_get_info (document);
399 if (!info || info->fields_mask == 0) {
400 has_properties = FALSE;
403 if (has_document && EV_IS_SELECTION (document)) {
407 if (has_pages && EV_IS_DOCUMENT_FIND (document)) {
411 if (has_document && ev_window->priv->settings) {
412 override_restrictions =
413 g_settings_get_boolean (ev_window->priv->settings,
414 GS_OVERRIDE_RESTRICTIONS);
417 if (!override_restrictions && info && info->fields_mask & EV_DOCUMENT_INFO_PERMISSIONS) {
418 ok_to_print = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_PRINT);
419 ok_to_copy = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_COPY);
422 if (has_document && !ev_print_operation_exists_for_document(document))
425 if (has_document && ev_window->priv->lockdown_settings &&
426 g_settings_get_boolean (ev_window->priv->lockdown_settings, GS_LOCKDOWN_SAVE)) {
430 if (has_document && ev_window->priv->lockdown_settings &&
431 g_settings_get_boolean (ev_window->priv->lockdown_settings, GS_LOCKDOWN_PRINT)) {
436 ev_window_set_action_sensitive (ev_window, "FileOpenCopy", has_document);
437 ev_window_set_action_sensitive (ev_window, "FileSaveAs", has_document && ok_to_copy);
438 ev_window_set_action_sensitive (ev_window, "FilePrint", has_pages && ok_to_print);
439 ev_window_set_action_sensitive (ev_window, "FileProperties", has_document && has_properties);
442 ev_window_set_action_sensitive (ev_window, "EditSelectAll", has_pages && can_get_text);
443 ev_window_set_action_sensitive (ev_window, "EditFind", can_find);
444 ev_window_set_action_sensitive (ev_window, "Slash", can_find);
445 ev_window_set_action_sensitive (ev_window, "EditRotateLeft", has_pages);
446 ev_window_set_action_sensitive (ev_window, "EditRotateRight", has_pages);
449 ev_window_set_action_sensitive (ev_window, "ViewContinuous", has_pages);
450 ev_window_set_action_sensitive (ev_window, "ViewDual", has_pages);
451 ev_window_set_action_sensitive (ev_window, "ViewBestFit", has_pages);
452 ev_window_set_action_sensitive (ev_window, "ViewPageWidth", has_pages);
453 ev_window_set_action_sensitive (ev_window, "ViewReload", has_pages);
454 ev_window_set_action_sensitive (ev_window, "ViewAutoscroll", has_pages);
455 ev_window_set_action_sensitive (ev_window, "ViewInvertedColors", has_pages);
458 ev_window_set_action_sensitive (ev_window, "BookmarksAdd",
459 has_pages && ev_window->priv->bookmarks);
461 /* Toolbar-specific actions: */
462 ev_window_set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages);
463 ev_window_set_action_sensitive (ev_window, ZOOM_CONTROL_ACTION, has_pages);
464 ev_window_set_action_sensitive (ev_window, NAVIGATION_ACTION, FALSE);
466 ev_window_update_actions (ev_window);
470 ev_window_update_actions (EvWindow *ev_window)
472 EvView *view = EV_VIEW (ev_window->priv->view);
473 int n_pages = 0, page = -1;
474 gboolean has_pages = FALSE;
475 gboolean presentation_mode;
476 gboolean can_find_in_page = FALSE;
477 EvSizingMode sizing_mode;
479 if (ev_window->priv->document) {
480 page = ev_document_model_get_page (ev_window->priv->model);
481 n_pages = ev_document_get_n_pages (ev_window->priv->document);
482 has_pages = n_pages > 0;
485 can_find_in_page = (ev_window->priv->find_job &&
486 ev_job_find_has_results (EV_JOB_FIND (ev_window->priv->find_job)));
488 ev_window_set_action_sensitive (ev_window, "EditCopy",
490 ev_view_get_has_selection (view));
491 ev_window_set_action_sensitive (ev_window, "EditFindNext",
492 has_pages && can_find_in_page);
493 ev_window_set_action_sensitive (ev_window, "EditFindPrevious",
494 has_pages && can_find_in_page);
495 ev_window_set_action_sensitive (ev_window, "F3",
496 has_pages && can_find_in_page);
498 presentation_mode = EV_WINDOW_IS_PRESENTATION (ev_window);
500 ev_window_set_action_sensitive (ev_window, "ViewZoomIn",
502 ev_view_can_zoom_in (view) &&
504 ev_window_set_action_sensitive (ev_window, "ViewZoomOut",
506 ev_view_can_zoom_out (view) &&
511 ev_window_set_action_sensitive (ev_window, "GoPreviousPage", page > 0);
512 ev_window_set_action_sensitive (ev_window, "GoNextPage", page < n_pages - 1);
513 ev_window_set_action_sensitive (ev_window, "GoFirstPage", page > 0);
514 ev_window_set_action_sensitive (ev_window, "GoLastPage", page < n_pages - 1);
516 ev_window_set_action_sensitive (ev_window, "GoFirstPage", FALSE);
517 ev_window_set_action_sensitive (ev_window, "GoPreviousPage", FALSE);
518 ev_window_set_action_sensitive (ev_window, "GoNextPage", FALSE);
519 ev_window_set_action_sensitive (ev_window, "GoLastPage", FALSE);
522 sizing_mode = ev_document_model_get_sizing_mode (ev_window->priv->model);
523 if (has_pages && sizing_mode != EV_SIZING_FIT_WIDTH && sizing_mode != EV_SIZING_BEST_FIT) {
528 action = gtk_action_group_get_action (ev_window->priv->action_group,
529 ZOOM_CONTROL_ACTION);
531 real_zoom = ev_document_model_get_scale (ev_window->priv->model);
532 real_zoom *= 72.0 / get_screen_dpi (ev_window);
533 zoom = ephy_zoom_get_nearest_zoom_level (real_zoom);
535 ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action), zoom);
540 ev_window_set_view_accels_sensitivity (EvWindow *window, gboolean sensitive)
544 can_find = window->priv->document &&
545 EV_IS_DOCUMENT_FIND (window->priv->document);
547 if (window->priv->action_group) {
548 ev_window_set_action_sensitive (window, "PageDown", sensitive);
549 ev_window_set_action_sensitive (window, "PageUp", sensitive);
550 ev_window_set_action_sensitive (window, "Space", sensitive);
551 ev_window_set_action_sensitive (window, "ShiftSpace", sensitive);
552 ev_window_set_action_sensitive (window, "BackSpace", sensitive);
553 ev_window_set_action_sensitive (window, "ShiftBackSpace", sensitive);
554 ev_window_set_action_sensitive (window, "Return", sensitive);
555 ev_window_set_action_sensitive (window, "ShiftReturn", sensitive);
556 ev_window_set_action_sensitive (window, "Plus", sensitive);
557 ev_window_set_action_sensitive (window, "Minus", sensitive);
558 ev_window_set_action_sensitive (window, "KpPlus", sensitive);
559 ev_window_set_action_sensitive (window, "KpMinus", sensitive);
560 ev_window_set_action_sensitive (window, "Equal", sensitive);
561 ev_window_set_action_sensitive (window, "p", sensitive);
562 ev_window_set_action_sensitive (window, "n", sensitive);
564 ev_window_set_action_sensitive (window, "Slash", sensitive && can_find);
569 set_widget_visibility (GtkWidget *widget, gboolean visible)
571 g_assert (GTK_IS_WIDGET (widget));
574 gtk_widget_show (widget);
576 gtk_widget_hide (widget);
580 update_chrome_visibility (EvWindow *window)
582 EvWindowPrivate *priv = window->priv;
583 gboolean menubar, toolbar, findbar, fullscreen_toolbar, sidebar;
584 gboolean fullscreen_mode, presentation, fullscreen;
586 presentation = EV_WINDOW_IS_PRESENTATION (window);
587 fullscreen = ev_document_model_get_fullscreen (priv->model);
588 fullscreen_mode = fullscreen || presentation;
590 menubar = (priv->chrome & EV_CHROME_MENUBAR) != 0 && !fullscreen_mode;
591 toolbar = ((priv->chrome & EV_CHROME_TOOLBAR) != 0 ||
592 (priv->chrome & EV_CHROME_RAISE_TOOLBAR) != 0) && !fullscreen_mode;
593 fullscreen_toolbar = ((priv->chrome & EV_CHROME_FULLSCREEN_TOOLBAR) != 0 ||
594 (priv->chrome & EV_CHROME_RAISE_TOOLBAR) != 0) && fullscreen;
595 findbar = (priv->chrome & EV_CHROME_FINDBAR) != 0;
596 sidebar = (priv->chrome & EV_CHROME_SIDEBAR) != 0 && priv->document && !presentation;
598 set_widget_visibility (priv->menubar, menubar);
599 set_widget_visibility (priv->toolbar, toolbar);
600 set_widget_visibility (priv->find_bar, findbar);
601 set_widget_visibility (priv->sidebar, sidebar);
603 ev_window_set_action_sensitive (window, "EditToolbar", toolbar);
605 if (priv->fullscreen_toolbar != NULL) {
606 set_widget_visibility (priv->fullscreen_toolbar, fullscreen_toolbar);
611 update_chrome_flag (EvWindow *window, EvChrome flag, gboolean active)
613 EvWindowPrivate *priv = window->priv;
616 priv->chrome |= flag;
618 priv->chrome &= ~flag;
623 update_sizing_buttons (EvWindow *window)
625 GtkActionGroup *action_group = window->priv->action_group;
627 gboolean best_fit, page_width;
629 switch (ev_document_model_get_sizing_mode (window->priv->model)) {
630 case EV_SIZING_BEST_FIT:
634 case EV_SIZING_FIT_WIDTH:
639 best_fit = page_width = FALSE;
643 action = gtk_action_group_get_action (action_group, "ViewBestFit");
644 g_signal_handlers_block_by_func
645 (action, G_CALLBACK (ev_window_cmd_view_best_fit), window);
646 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), best_fit);
647 g_signal_handlers_unblock_by_func
648 (action, G_CALLBACK (ev_window_cmd_view_best_fit), window);
650 action = gtk_action_group_get_action (action_group, "ViewPageWidth");
651 g_signal_handlers_block_by_func
652 (action, G_CALLBACK (ev_window_cmd_view_page_width), window);
653 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), page_width);
654 g_signal_handlers_unblock_by_func
655 (action, G_CALLBACK (ev_window_cmd_view_page_width), window);
657 action = gtk_action_group_get_action (window->priv->action_group,
658 ZOOM_CONTROL_ACTION);
660 ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action),
662 } else if (page_width) {
663 ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action),
664 EPHY_ZOOM_FIT_WIDTH);
669 update_chrome_actions (EvWindow *window)
671 EvWindowPrivate *priv = window->priv;
672 GtkActionGroup *action_group = priv->action_group;
675 action= gtk_action_group_get_action (action_group, "ViewToolbar");
676 g_signal_handlers_block_by_func
677 (action, G_CALLBACK (ev_window_view_toolbar_cb), window);
678 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
679 (priv->chrome & EV_CHROME_TOOLBAR) != 0);
680 g_signal_handlers_unblock_by_func
681 (action, G_CALLBACK (ev_window_view_toolbar_cb), window);
685 * ev_window_is_empty:
686 * @ev_window: The instance of the #EvWindow.
688 * It does look if there is any document loaded or if there is any job to load
691 * Returns: %TRUE if there isn't any document loaded or any any documente to be
692 * loaded, %FALSE in other case.
695 ev_window_is_empty (const EvWindow *ev_window)
697 g_return_val_if_fail (EV_IS_WINDOW (ev_window), FALSE);
699 return (ev_window->priv->document == NULL) &&
700 (ev_window->priv->load_job == NULL);
704 ev_window_set_message_area (EvWindow *window,
707 if (window->priv->message_area == area)
710 if (window->priv->message_area)
711 gtk_widget_destroy (window->priv->message_area);
712 window->priv->message_area = area;
717 gtk_box_pack_start (GTK_BOX (window->priv->view_box),
718 window->priv->message_area,
720 gtk_box_reorder_child (GTK_BOX (window->priv->view_box),
721 window->priv->message_area, 0);
722 g_object_add_weak_pointer (G_OBJECT (window->priv->message_area),
723 (gpointer) &(window->priv->message_area));
727 ev_window_message_area_response_cb (EvMessageArea *area,
731 ev_window_set_message_area (window, NULL);
735 ev_window_error_message (EvWindow *window,
744 if (window->priv->message_area)
747 va_start (args, format);
748 msg = g_strdup_vprintf (format, args);
751 area = ev_message_area_new (GTK_MESSAGE_ERROR,
759 ev_message_area_set_secondary_text (EV_MESSAGE_AREA (area), error->message);
760 g_signal_connect (area, "response",
761 G_CALLBACK (ev_window_message_area_response_cb),
763 gtk_widget_show (area);
764 ev_window_set_message_area (window, area);
768 ev_window_warning_message (EvWindow *window,
776 if (window->priv->message_area)
779 va_start (args, format);
780 msg = g_strdup_vprintf (format, args);
783 area = ev_message_area_new (GTK_MESSAGE_WARNING,
790 g_signal_connect (area, "response",
791 G_CALLBACK (ev_window_message_area_response_cb),
793 gtk_widget_show (area);
794 ev_window_set_message_area (window, area);
797 typedef struct _PageTitleData {
798 const gchar *page_label;
803 ev_window_find_page_title (GtkTreeModel *tree_model,
810 gtk_tree_model_get (tree_model, iter,
811 EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, &page_string,
817 if (!strcmp (page_string, data->page_label)) {
818 gtk_tree_model_get (tree_model, iter,
819 EV_DOCUMENT_LINKS_COLUMN_MARKUP, &data->page_title,
821 g_free (page_string);
825 g_free (page_string);
830 ev_window_get_page_title (EvWindow *window,
831 const gchar *page_label)
833 if (EV_IS_DOCUMENT_LINKS (window->priv->document) &&
834 ev_document_links_has_document_links (EV_DOCUMENT_LINKS (window->priv->document))) {
838 data.page_label = page_label;
839 data.page_title = NULL;
841 g_object_get (G_OBJECT (window->priv->sidebar_links),
845 gtk_tree_model_foreach (model,
846 (GtkTreeModelForeachFunc)ev_window_find_page_title,
849 g_object_unref (model);
852 return data.page_title;
859 ev_window_add_history (EvWindow *window, gint page, EvLink *link)
861 gchar *page_label = NULL;
865 EvLinkAction *action;
868 if (window->priv->history == NULL)
871 if (!EV_IS_DOCUMENT_LINKS (window->priv->document))
875 action = g_object_ref (ev_link_get_action (link));
876 dest = ev_link_action_get_dest (action);
877 page_label = ev_document_links_get_dest_page_label (EV_DOCUMENT_LINKS (window->priv->document), dest);
879 dest = ev_link_dest_new_page (page);
880 action = ev_link_action_new_dest (dest);
881 page_label = ev_document_get_page_label (window->priv->document, page);
887 page_title = ev_window_get_page_title (window, page_label);
889 link_title = g_strdup_printf (_("Page %s — %s"), page_label, page_title);
892 link_title = g_strdup_printf (_("Page %s"), page_label);
895 real_link = ev_link_new (link_title, action);
897 ev_history_add_link (window->priv->history, real_link);
901 g_object_unref (real_link);
905 view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window)
907 int current_page = ev_document_model_get_page (window->priv->model);
909 ev_window_add_history (window, 0, link);
910 ev_window_add_history (window, current_page, NULL);
914 view_selection_changed_cb (EvView *view,
917 ev_window_set_action_sensitive (window, "EditCopy",
918 ev_view_get_has_selection (view));
922 view_layers_changed_cb (EvView *view,
925 ev_sidebar_layers_update_layers_state (EV_SIDEBAR_LAYERS (window->priv->sidebar_layers));
929 ev_window_page_changed_cb (EvWindow *ev_window,
932 EvDocumentModel *model)
934 ev_window_update_actions (ev_window);
936 ev_window_update_find_status_message (ev_window);
938 if (abs (new_page - old_page) > 1) {
939 ev_window_add_history (ev_window, new_page, NULL);
940 ev_window_add_history (ev_window, old_page, NULL);
943 if (ev_window->priv->metadata && !ev_window_is_empty (ev_window))
944 ev_metadata_set_int (ev_window->priv->metadata, "page", new_page);
948 ev_window_sidebar_get_current_page_id (EvWindow *ev_window)
950 GtkWidget *current_page;
953 g_object_get (ev_window->priv->sidebar,
954 "current_page", ¤t_page,
957 if (current_page == ev_window->priv->sidebar_links) {
958 id = LINKS_SIDEBAR_ID;
959 } else if (current_page == ev_window->priv->sidebar_thumbs) {
960 id = THUMBNAILS_SIDEBAR_ID;
961 } else if (current_page == ev_window->priv->sidebar_attachments) {
962 id = ATTACHMENTS_SIDEBAR_ID;
963 } else if (current_page == ev_window->priv->sidebar_layers) {
964 id = LAYERS_SIDEBAR_ID;
965 } else if (current_page == ev_window->priv->sidebar_annots) {
966 id = ANNOTS_SIDEBAR_ID;
968 g_assert_not_reached();
971 g_object_unref (current_page);
977 ev_window_sidebar_set_current_page (EvWindow *window,
978 const gchar *page_id)
980 EvDocument *document = window->priv->document;
981 EvSidebar *sidebar = EV_SIDEBAR (window->priv->sidebar);
982 GtkWidget *links = window->priv->sidebar_links;
983 GtkWidget *thumbs = window->priv->sidebar_thumbs;
984 GtkWidget *attachments = window->priv->sidebar_attachments;
985 GtkWidget *annots = window->priv->sidebar_annots;
986 GtkWidget *layers = window->priv->sidebar_layers;
988 if (strcmp (page_id, LINKS_SIDEBAR_ID) == 0 &&
989 ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) {
990 ev_sidebar_set_page (sidebar, links);
991 } else if (strcmp (page_id, THUMBNAILS_SIDEBAR_ID) == 0 &&
992 ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) {
993 ev_sidebar_set_page (sidebar, thumbs);
994 } else if (strcmp (page_id, ATTACHMENTS_SIDEBAR_ID) == 0 &&
995 ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) {
996 ev_sidebar_set_page (sidebar, attachments);
997 } else if (strcmp (page_id, LAYERS_SIDEBAR_ID) == 0 &&
998 ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (layers), document)) {
999 ev_sidebar_set_page (sidebar, layers);
1000 } else if (strcmp (page_id, ANNOTS_SIDEBAR_ID) == 0 &&
1001 ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (annots), document)) {
1002 ev_sidebar_set_page (sidebar, annots);
1007 update_document_mode (EvWindow *window, EvDocumentMode mode)
1009 if (mode == EV_DOCUMENT_MODE_PRESENTATION) {
1010 ev_window_run_presentation (window);
1012 else if (mode == EV_DOCUMENT_MODE_FULL_SCREEN) {
1013 ev_window_run_fullscreen (window);
1018 setup_chrome_from_metadata (EvWindow *window)
1020 EvChrome chrome = EV_CHROME_NORMAL;
1021 gboolean show_toolbar = TRUE;
1023 if (ev_window_is_empty (window)) {
1024 window->priv->chrome = chrome;
1029 if (!window->priv->metadata) {
1030 show_toolbar = g_settings_get_boolean (window->priv->default_settings, "show-toolbar");
1031 } else if (!ev_metadata_get_boolean (window->priv->metadata, "show_toolbar", &show_toolbar)) {
1032 if (window->priv->is_new_doc)
1033 show_toolbar = g_settings_get_boolean (window->priv->default_settings, "show-toolbar");
1037 chrome &= ~EV_CHROME_TOOLBAR;
1039 window->priv->chrome = chrome;
1043 setup_sidebar_from_metadata (EvWindow *window)
1045 EvDocument *document = window->priv->document;
1046 GSettings *settings = window->priv->default_settings;
1049 gboolean sidebar_visibility = TRUE;
1051 if (ev_window_is_empty (window))
1054 if (!window->priv->metadata) {
1055 sidebar_visibility = g_settings_get_boolean (settings, "show-sidebar");
1056 } else if (!ev_metadata_get_boolean (window->priv->metadata, "sidebar_visibility", &sidebar_visibility)) {
1057 if (window->priv->is_new_doc)
1058 sidebar_visibility = g_settings_get_boolean (settings, "show-sidebar");
1061 update_chrome_flag (window, EV_CHROME_SIDEBAR, sidebar_visibility);
1062 update_chrome_visibility (window);
1064 if (!window->priv->metadata) {
1065 /* Set default values */
1066 gtk_paned_set_position (GTK_PANED (window->priv->hpaned),
1067 g_settings_get_int (settings, "sidebar-size"));
1069 page_id = g_settings_get_string (settings, "sidebar-page");
1070 ev_window_sidebar_set_current_page (window, page_id);
1077 if (ev_metadata_get_int (window->priv->metadata, "sidebar_size", &sidebar_size)) {
1078 gtk_paned_set_position (GTK_PANED (window->priv->hpaned), sidebar_size);
1079 } else if (window->priv->is_new_doc) {
1080 gtk_paned_set_position (GTK_PANED (window->priv->hpaned),
1081 g_settings_get_int (settings, "sidebar-size"));
1087 if (ev_metadata_get_string (window->priv->metadata, "sidebar_page", &page_id)) {
1088 ev_window_sidebar_set_current_page (window, page_id);
1089 } else if (window->priv->is_new_doc) {
1090 page_id = g_settings_get_string (settings, "sidebar-page");
1091 ev_window_sidebar_set_current_page (window, page_id);
1097 setup_model_from_metadata (EvWindow *window)
1099 GSettings *settings = window->priv->default_settings;
1104 gboolean inverted_colors = FALSE;
1105 gboolean continuous = FALSE;
1106 gboolean dual_page = FALSE;
1107 gboolean fullscreen = FALSE;
1109 if (!window->priv->metadata) {
1110 /* Set default values */
1111 ev_document_model_set_sizing_mode (window->priv->model,
1112 g_settings_get_enum (settings, "sizing-mode"));
1113 ev_document_model_set_inverted_colors (window->priv->model,
1114 g_settings_get_boolean (settings, "inverted-colors"));
1115 ev_document_model_set_continuous (window->priv->model,
1116 g_settings_get_boolean (settings, "continuous"));
1117 ev_document_model_set_dual_page (window->priv->model,
1118 g_settings_get_boolean (settings, "dual-page"));
1119 fullscreen = g_settings_get_boolean (settings, "fullscreen");
1121 ev_window_run_fullscreen (window);
1127 if (!window->priv->dest &&
1128 ev_metadata_get_int (window->priv->metadata, "page", &page)) {
1129 ev_document_model_set_page (window->priv->model, page);
1133 if (ev_metadata_get_string (window->priv->metadata, "sizing_mode", &sizing_mode)) {
1134 GEnumValue *enum_value;
1136 enum_value = g_enum_get_value_by_nick
1137 (g_type_class_peek (EV_TYPE_SIZING_MODE), sizing_mode);
1138 ev_document_model_set_sizing_mode (window->priv->model, enum_value->value);
1139 } else if (window->priv->is_new_doc) {
1140 ev_document_model_set_sizing_mode (window->priv->model,
1141 g_settings_get_enum (settings, "sizing-mode"));
1145 if (ev_document_model_get_sizing_mode (window->priv->model) == EV_SIZING_FREE &&
1146 ev_metadata_get_double (window->priv->metadata, "zoom", &zoom)) {
1147 zoom *= get_screen_dpi (window) / 72.0;
1148 ev_document_model_set_scale (window->priv->model, zoom);
1152 if (ev_metadata_get_int (window->priv->metadata, "rotation", &rotation)) {
1167 ev_document_model_set_rotation (window->priv->model, rotation);
1170 /* Inverted Colors */
1171 if (ev_metadata_get_boolean (window->priv->metadata, "inverted-colors", &inverted_colors)) {
1172 ev_document_model_set_inverted_colors (window->priv->model, inverted_colors);
1173 } else if (window->priv->is_new_doc) {
1174 ev_document_model_set_inverted_colors (window->priv->model,
1175 g_settings_get_boolean (settings, "inverted-colors"));
1179 if (ev_metadata_get_boolean (window->priv->metadata, "continuous", &continuous)) {
1180 ev_document_model_set_continuous (window->priv->model, continuous);
1181 } else if (window->priv->is_new_doc) {
1182 ev_document_model_set_continuous (window->priv->model,
1183 g_settings_get_boolean (settings, "continuous"));
1187 if (ev_metadata_get_boolean (window->priv->metadata, "dual-page", &dual_page)) {
1188 ev_document_model_set_dual_page (window->priv->model, dual_page);
1189 } else if (window->priv->is_new_doc) {
1190 ev_document_model_set_dual_page (window->priv->model,
1191 g_settings_get_boolean (settings, "dual-page"));
1195 if (!ev_metadata_get_boolean (window->priv->metadata, "fullscreen", &fullscreen)) {
1196 if (window->priv->is_new_doc)
1197 fullscreen = g_settings_get_boolean (settings, "fullscreen");
1201 ev_window_run_fullscreen (window);
1205 setup_document_from_metadata (EvWindow *window)
1210 gdouble width_ratio;
1211 gdouble height_ratio;
1213 setup_sidebar_from_metadata (window);
1215 if (window->priv->metadata) {
1216 /* Make sure to not open a document on the last page,
1217 * since closing it on the last page most likely means the
1218 * user was finished reading the document. In that case, reopening should
1219 * show the first page. */
1220 page = ev_document_model_get_page (window->priv->model);
1221 n_pages = ev_document_get_n_pages (window->priv->document);
1222 if (page == n_pages - 1)
1223 ev_document_model_set_page (window->priv->model, 0);
1225 if (ev_metadata_get_int (window->priv->metadata, "window_width", &width) &&
1226 ev_metadata_get_int (window->priv->metadata, "window_height", &height))
1227 return; /* size was already set in setup_size_from_metadata */
1230 g_settings_get (window->priv->default_settings, "window-ratio", "(dd)", &width_ratio, &height_ratio);
1231 if (width_ratio > 0. && height_ratio > 0.) {
1232 gdouble document_width;
1233 gdouble document_height;
1236 gint request_height;
1238 ev_document_get_max_page_size (window->priv->document,
1239 &document_width, &document_height);
1241 request_width = (gint)(width_ratio * document_width + 0.5);
1242 request_height = (gint)(height_ratio * document_height + 0.5);
1244 screen = gtk_window_get_screen (GTK_WINDOW (window));
1246 request_width = MIN (request_width, gdk_screen_get_width (screen));
1247 request_height = MIN (request_height, gdk_screen_get_height (screen));
1250 if (request_width > 0 && request_height > 0) {
1251 gtk_window_resize (GTK_WINDOW (window),
1259 setup_size_from_metadata (EvWindow *window)
1267 if (!window->priv->metadata)
1270 if (ev_metadata_get_boolean (window->priv->metadata, "window_maximized", &maximized)) {
1272 gtk_window_maximize (GTK_WINDOW (window));
1275 gtk_window_unmaximize (GTK_WINDOW (window));
1279 if (ev_metadata_get_int (window->priv->metadata, "window_x", &x) &&
1280 ev_metadata_get_int (window->priv->metadata, "window_y", &y)) {
1281 gtk_window_move (GTK_WINDOW (window), x, y);
1284 if (ev_metadata_get_int (window->priv->metadata, "window_width", &width) &&
1285 ev_metadata_get_int (window->priv->metadata, "window_height", &height)) {
1286 gtk_window_resize (GTK_WINDOW (window), width, height);
1291 setup_view_from_metadata (EvWindow *window)
1293 gboolean presentation;
1295 if (!window->priv->metadata)
1299 if (ev_metadata_get_boolean (window->priv->metadata, "presentation", &presentation)) {
1301 ev_window_run_presentation (window);
1307 ev_window_clear_thumbnail_job (EvWindow *ev_window)
1309 if (ev_window->priv->thumbnail_job != NULL) {
1310 if (!ev_job_is_finished (ev_window->priv->thumbnail_job))
1311 ev_job_cancel (ev_window->priv->thumbnail_job);
1313 g_signal_handlers_disconnect_by_func (ev_window->priv->thumbnail_job,
1314 ev_window_set_icon_from_thumbnail,
1316 g_object_unref (ev_window->priv->thumbnail_job);
1317 ev_window->priv->thumbnail_job = NULL;
1322 ev_window_set_icon_from_thumbnail (EvJobThumbnail *job,
1323 EvWindow *ev_window)
1325 if (job->thumbnail) {
1326 if (ev_document_model_get_inverted_colors (ev_window->priv->model))
1327 ev_document_misc_invert_pixbuf (job->thumbnail);
1328 gtk_window_set_icon (GTK_WINDOW (ev_window),
1332 ev_window_clear_thumbnail_job (ev_window);
1336 ev_window_refresh_window_thumbnail (EvWindow *ev_window)
1341 EvDocument *document = ev_window->priv->document;
1343 if (ev_document_get_n_pages (document) <= 0 ||
1344 !ev_document_check_dimensions (document)) {
1348 ev_window_clear_thumbnail_job (ev_window);
1350 ev_document_get_page_size (document, 0, &page_width, NULL);
1351 scale = 128. / page_width;
1352 rotation = ev_document_model_get_rotation (ev_window->priv->model);
1354 ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, 0, rotation, scale);
1355 g_signal_connect (ev_window->priv->thumbnail_job, "finished",
1356 G_CALLBACK (ev_window_set_icon_from_thumbnail),
1358 ev_job_scheduler_push_job (ev_window->priv->thumbnail_job, EV_JOB_PRIORITY_NONE);
1362 override_restrictions_changed (GSettings *settings,
1364 EvWindow *ev_window)
1366 ev_window_setup_action_sensitivity (ev_window);
1370 lockdown_changed (GSettings *lockdown,
1372 EvWindow *ev_window)
1374 ev_window_setup_action_sensitivity (ev_window);
1378 ev_window_setup_document (EvWindow *ev_window)
1380 const EvDocumentInfo *info;
1381 EvDocument *document = ev_window->priv->document;
1384 ev_window->priv->setup_document_idle = 0;
1386 ev_window_refresh_window_thumbnail (ev_window);
1388 ev_window_set_page_mode (ev_window, PAGE_MODE_DOCUMENT);
1389 ev_window_title_set_document (ev_window->priv->title, document);
1390 ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri);
1392 if (!ev_window->priv->settings) {
1393 ev_window->priv->settings = g_settings_new (GS_SCHEMA_NAME);
1394 g_signal_connect (ev_window->priv->settings,
1395 "changed::"GS_OVERRIDE_RESTRICTIONS,
1396 G_CALLBACK (override_restrictions_changed),
1400 #ifdef HAVE_DESKTOP_SCHEMAS
1401 if (!ev_window->priv->lockdown_settings) {
1402 ev_window->priv->lockdown_settings = g_settings_new (GS_LOCKDOWN_SCHEMA_NAME);
1403 g_signal_connect (ev_window->priv->lockdown_settings,
1405 G_CALLBACK (lockdown_changed),
1410 ev_window_setup_action_sensitivity (ev_window);
1412 if (ev_window->priv->history)
1413 g_object_unref (ev_window->priv->history);
1414 ev_window->priv->history = ev_history_new ();
1415 action = gtk_action_group_get_action (ev_window->priv->action_group, NAVIGATION_ACTION);
1416 ev_navigation_action_set_history (EV_NAVIGATION_ACTION (action), ev_window->priv->history);
1418 if (ev_window->priv->properties) {
1419 ev_properties_dialog_set_document (EV_PROPERTIES_DIALOG (ev_window->priv->properties),
1420 ev_window->priv->uri,
1421 ev_window->priv->document);
1424 info = ev_document_get_info (document);
1425 update_document_mode (ev_window, info->mode);
1427 if (EV_WINDOW_IS_PRESENTATION (ev_window))
1428 gtk_widget_grab_focus (ev_window->priv->presentation_view);
1430 gtk_widget_grab_focus (ev_window->priv->view);
1436 ev_window_set_document (EvWindow *ev_window, EvDocument *document)
1438 if (ev_window->priv->document == document)
1441 if (ev_window->priv->document)
1442 g_object_unref (ev_window->priv->document);
1443 ev_window->priv->document = g_object_ref (document);
1445 ev_window_update_max_min_scale (ev_window);
1447 ev_window_set_message_area (ev_window, NULL);
1449 if (ev_document_get_n_pages (document) <= 0) {
1450 ev_window_warning_message (ev_window, "%s",
1451 _("The document contains no pages"));
1452 } else if (!ev_document_check_dimensions (document)) {
1453 ev_window_warning_message (ev_window, "%s",
1454 _("The document contains only empty pages"));
1457 if (EV_WINDOW_IS_PRESENTATION (ev_window)) {
1458 gtk_widget_destroy (ev_window->priv->presentation_view);
1459 ev_window->priv->presentation_view = NULL;
1460 ev_window_run_presentation (ev_window);
1463 if (ev_window->priv->setup_document_idle > 0)
1464 g_source_remove (ev_window->priv->setup_document_idle);
1466 ev_window->priv->setup_document_idle = g_idle_add ((GSourceFunc)ev_window_setup_document, ev_window);
1470 ev_window_document_changed (EvWindow *ev_window,
1473 ev_window_reload_document (ev_window, NULL);
1477 ev_window_password_view_unlock (EvWindow *ev_window)
1479 const gchar *password;
1481 g_assert (ev_window->priv->load_job);
1483 password = ev_password_view_get_password (EV_PASSWORD_VIEW (ev_window->priv->password_view));
1484 ev_job_load_set_password (EV_JOB_LOAD (ev_window->priv->load_job), password);
1485 ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
1489 ev_window_clear_load_job (EvWindow *ev_window)
1491 if (ev_window->priv->load_job != NULL) {
1492 if (!ev_job_is_finished (ev_window->priv->load_job))
1493 ev_job_cancel (ev_window->priv->load_job);
1495 g_signal_handlers_disconnect_by_func (ev_window->priv->load_job, ev_window_load_job_cb, ev_window);
1496 g_object_unref (ev_window->priv->load_job);
1497 ev_window->priv->load_job = NULL;
1502 ev_window_clear_reload_job (EvWindow *ev_window)
1504 if (ev_window->priv->reload_job != NULL) {
1505 if (!ev_job_is_finished (ev_window->priv->reload_job))
1506 ev_job_cancel (ev_window->priv->reload_job);
1508 g_signal_handlers_disconnect_by_func (ev_window->priv->reload_job, ev_window_reload_job_cb, ev_window);
1509 g_object_unref (ev_window->priv->reload_job);
1510 ev_window->priv->reload_job = NULL;
1515 ev_window_clear_local_uri (EvWindow *ev_window)
1517 if (ev_window->priv->local_uri) {
1518 ev_tmp_uri_unlink (ev_window->priv->local_uri);
1519 g_free (ev_window->priv->local_uri);
1520 ev_window->priv->local_uri = NULL;
1525 ev_window_handle_link (EvWindow *ev_window,
1530 EvLinkAction *link_action;
1532 link_action = ev_link_action_new_dest (dest);
1533 link = ev_link_new (NULL, link_action);
1534 ev_view_handle_link (EV_VIEW (ev_window->priv->view), link);
1535 g_object_unref (link);
1539 /* This callback will executed when load job will be finished.
1541 * Since the flow of the error dialog is very confusing, we assume that both
1542 * document and uri will go away after this function is called, and thus we need
1543 * to ref/dup them. Additionally, it needs to clear
1544 * ev_window->priv->password_{uri,document}, and thus people who call this
1545 * function should _not_ necessarily expect those to exist after being
1548 ev_window_load_job_cb (EvJob *job,
1551 EvWindow *ev_window = EV_WINDOW (data);
1552 EvDocument *document = EV_JOB (job)->document;
1553 EvJobLoad *job_load = EV_JOB_LOAD (job);
1555 g_assert (job_load->uri);
1557 ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
1560 if (!ev_job_is_failed (job)) {
1561 ev_document_model_set_document (ev_window->priv->model, document);
1564 ev_window_emit_doc_loaded (ev_window);
1566 setup_chrome_from_metadata (ev_window);
1567 update_chrome_actions (ev_window);
1568 setup_document_from_metadata (ev_window);
1569 setup_view_from_metadata (ev_window);
1571 ev_window_add_recent (ev_window, ev_window->priv->uri);
1573 ev_window_title_set_type (ev_window->priv->title,
1574 EV_WINDOW_TITLE_DOCUMENT);
1575 if (job_load->password) {
1576 GPasswordSave flags;
1578 flags = ev_password_view_get_password_save_flags (
1579 EV_PASSWORD_VIEW (ev_window->priv->password_view));
1580 ev_keyring_save_password (ev_window->priv->uri,
1585 ev_window_handle_link (ev_window, ev_window->priv->dest);
1586 /* Already unrefed by ev_link_action
1587 * FIXME: link action should inc dest ref counting
1588 * or not unref it at all
1590 ev_window->priv->dest = NULL;
1592 switch (ev_window->priv->window_mode) {
1593 case EV_WINDOW_MODE_FULLSCREEN:
1594 ev_window_run_fullscreen (ev_window);
1596 case EV_WINDOW_MODE_PRESENTATION:
1597 ev_window_run_presentation (ev_window);
1603 if (ev_window->priv->search_string && EV_IS_DOCUMENT_FIND (document)) {
1604 ev_window_cmd_edit_find (NULL, ev_window);
1605 egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar),
1606 ev_window->priv->search_string);
1609 g_free (ev_window->priv->search_string);
1610 ev_window->priv->search_string = NULL;
1612 /* Create a monitor for the document */
1613 ev_window->priv->monitor = ev_file_monitor_new (ev_window->priv->uri);
1614 g_signal_connect_swapped (ev_window->priv->monitor, "changed",
1615 G_CALLBACK (ev_window_document_changed),
1618 ev_window_clear_load_job (ev_window);
1622 if (g_error_matches (job->error, EV_DOCUMENT_ERROR, EV_DOCUMENT_ERROR_ENCRYPTED)) {
1625 setup_view_from_metadata (ev_window);
1627 /* First look whether password is in keyring */
1628 password = ev_keyring_lookup_password (ev_window->priv->uri);
1630 if (job_load->password && strcmp (password, job_load->password) == 0) {
1631 /* Password in kering is wrong */
1632 ev_job_load_set_password (job_load, NULL);
1633 /* FIXME: delete password from keyring? */
1635 ev_job_load_set_password (job_load, password);
1636 ev_job_scheduler_push_job (job, EV_JOB_PRIORITY_NONE);
1644 /* We need to ask the user for a password */
1645 ev_window_title_set_uri (ev_window->priv->title,
1646 ev_window->priv->uri);
1647 ev_window_title_set_type (ev_window->priv->title,
1648 EV_WINDOW_TITLE_PASSWORD);
1650 ev_password_view_set_uri (EV_PASSWORD_VIEW (ev_window->priv->password_view),
1653 ev_window_set_page_mode (ev_window, PAGE_MODE_PASSWORD);
1655 ev_job_load_set_password (job_load, NULL);
1656 ev_password_view_ask_password (EV_PASSWORD_VIEW (ev_window->priv->password_view));
1658 ev_window_error_message (ev_window, job->error,
1659 "%s", _("Unable to open document"));
1660 ev_window_clear_load_job (ev_window);
1665 ev_window_reload_job_cb (EvJob *job,
1666 EvWindow *ev_window)
1670 if (ev_job_is_failed (job)) {
1671 ev_window_clear_reload_job (ev_window);
1672 ev_window->priv->in_reload = FALSE;
1673 if (ev_window->priv->dest) {
1674 g_object_unref (ev_window->priv->dest);
1675 ev_window->priv->dest = NULL;
1681 ev_document_model_set_document (ev_window->priv->model,
1683 if (ev_window->priv->dest) {
1684 ev_window_handle_link (ev_window, ev_window->priv->dest);
1685 /* Already unrefed by ev_link_action
1686 * FIXME: link action should inc dest ref counting
1687 * or not unref it at all
1689 ev_window->priv->dest = NULL;
1692 /* Restart the search after reloading */
1693 widget = gtk_window_get_focus (GTK_WINDOW (ev_window));
1694 if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) {
1695 find_bar_search_changed_cb (EGG_FIND_BAR (ev_window->priv->find_bar),
1699 ev_window_clear_reload_job (ev_window);
1700 ev_window->priv->in_reload = FALSE;
1704 * ev_window_get_uri:
1705 * @ev_window: The instance of the #EvWindow.
1707 * It returns the uri of the document showed in the #EvWindow.
1709 * Returns: the uri of the document showed in the #EvWindow.
1712 ev_window_get_uri (EvWindow *ev_window)
1714 return ev_window->priv->uri;
1718 * ev_window_close_dialogs:
1719 * @ev_window: The window where dialogs will be closed.
1721 * It looks for password, print and properties dialogs and closes them and
1722 * frees them from memory. If there is any print job it does free it too.
1725 ev_window_close_dialogs (EvWindow *ev_window)
1727 if (ev_window->priv->print_dialog)
1728 gtk_widget_destroy (ev_window->priv->print_dialog);
1729 ev_window->priv->print_dialog = NULL;
1731 if (ev_window->priv->properties)
1732 gtk_widget_destroy (ev_window->priv->properties);
1733 ev_window->priv->properties = NULL;
1737 ev_window_clear_progress_idle (EvWindow *ev_window)
1739 if (ev_window->priv->progress_idle > 0)
1740 g_source_remove (ev_window->priv->progress_idle);
1741 ev_window->priv->progress_idle = 0;
1745 reset_progress_idle (EvWindow *ev_window)
1747 ev_window->priv->progress_idle = 0;
1751 ev_window_show_progress_message (EvWindow *ev_window,
1753 GSourceFunc function)
1755 if (ev_window->priv->progress_idle > 0)
1756 g_source_remove (ev_window->priv->progress_idle);
1757 ev_window->priv->progress_idle =
1758 g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
1761 (GDestroyNotify)reset_progress_idle);
1765 ev_window_reset_progress_cancellable (EvWindow *ev_window)
1767 if (ev_window->priv->progress_cancellable)
1768 g_cancellable_reset (ev_window->priv->progress_cancellable);
1770 ev_window->priv->progress_cancellable = g_cancellable_new ();
1774 ev_window_progress_response_cb (EvProgressMessageArea *area,
1776 EvWindow *ev_window)
1778 if (response == GTK_RESPONSE_CANCEL)
1779 g_cancellable_cancel (ev_window->priv->progress_cancellable);
1780 ev_window_set_message_area (ev_window, NULL);
1784 show_loading_progress (EvWindow *ev_window)
1788 gchar *display_name;
1790 if (ev_window->priv->message_area)
1793 text = g_uri_unescape_string (ev_window->priv->uri, NULL);
1794 display_name = g_markup_escape_text (text, -1);
1796 text = g_strdup_printf (_("Loading document from “%s”"),
1799 area = ev_progress_message_area_new (GTK_STOCK_OPEN,
1804 GTK_RESPONSE_CANCEL,
1806 g_signal_connect (area, "response",
1807 G_CALLBACK (ev_window_progress_response_cb),
1809 gtk_widget_show (area);
1810 ev_window_set_message_area (ev_window, area);
1813 g_free (display_name);
1819 ev_window_load_remote_failed (EvWindow *ev_window,
1822 ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
1823 ev_window->priv->in_reload = FALSE;
1824 ev_window_error_message (ev_window, error,
1825 "%s", _("Unable to open document"));
1826 g_free (ev_window->priv->local_uri);
1827 ev_window->priv->local_uri = NULL;
1828 ev_window->priv->uri_mtime = 0;
1832 set_uri_mtime (GFile *source,
1833 GAsyncResult *async_result,
1834 EvWindow *ev_window)
1837 GError *error = NULL;
1839 info = g_file_query_info_finish (source, async_result, &error);
1842 ev_window->priv->uri_mtime = 0;
1843 g_error_free (error);
1847 g_file_info_get_modification_time (info, &mtime);
1848 ev_window->priv->uri_mtime = mtime.tv_sec;
1849 g_object_unref (info);
1852 g_object_unref (source);
1856 mount_volume_ready_cb (GFile *source,
1857 GAsyncResult *async_result,
1858 EvWindow *ev_window)
1860 GError *error = NULL;
1862 g_file_mount_enclosing_volume_finish (source, async_result, &error);
1865 ev_window_load_remote_failed (ev_window, error);
1866 g_object_unref (source);
1867 g_error_free (error);
1869 /* Volume successfully mounted,
1870 try opening the file again */
1871 ev_window_load_file_remote (ev_window, source);
1876 window_open_file_copy_ready_cb (GFile *source,
1877 GAsyncResult *async_result,
1878 EvWindow *ev_window)
1880 GError *error = NULL;
1882 ev_window_clear_progress_idle (ev_window);
1883 ev_window_set_message_area (ev_window, NULL);
1885 g_file_copy_finish (source, async_result, &error);
1887 ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
1888 g_file_query_info_async (source,
1889 G_FILE_ATTRIBUTE_TIME_MODIFIED,
1890 0, G_PRIORITY_DEFAULT,
1892 (GAsyncReadyCallback)set_uri_mtime,
1897 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED)) {
1898 GMountOperation *operation;
1900 operation = gtk_mount_operation_new (GTK_WINDOW (ev_window));
1901 g_file_mount_enclosing_volume (source,
1904 (GAsyncReadyCallback)mount_volume_ready_cb,
1906 g_object_unref (operation);
1907 } else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
1908 ev_window_clear_load_job (ev_window);
1909 ev_window_clear_local_uri (ev_window);
1910 g_free (ev_window->priv->uri);
1911 ev_window->priv->uri = NULL;
1912 g_object_unref (source);
1914 ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);
1916 ev_window_load_remote_failed (ev_window, error);
1917 g_object_unref (source);
1920 g_error_free (error);
1924 window_open_file_copy_progress_cb (goffset n_bytes,
1925 goffset total_bytes,
1926 EvWindow *ev_window)
1931 if (!ev_window->priv->message_area)
1934 if (total_bytes <= 0)
1937 fraction = n_bytes / (gdouble)total_bytes;
1938 status = g_strdup_printf (_("Downloading document (%d%%)"),
1939 (gint)(fraction * 100));
1941 ev_progress_message_area_set_status (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
1943 ev_progress_message_area_set_fraction (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
1950 ev_window_load_file_remote (EvWindow *ev_window,
1955 if (!ev_window->priv->local_uri) {
1956 char *base_name, *template;
1960 /* We'd like to keep extension of source uri since
1961 * it helps to resolve some mime types, say cbz.
1963 base_name = g_file_get_basename (source_file);
1964 template = g_strdup_printf ("document.XXXXXX-%s", base_name);
1967 tmp_file = ev_mkstemp_file (template, &err);
1969 if (tmp_file == NULL) {
1970 ev_window_error_message (ev_window, err,
1971 "%s", _("Failed to load remote file."));
1976 ev_window->priv->local_uri = g_file_get_uri (tmp_file);
1977 g_object_unref (tmp_file);
1979 ev_job_load_set_uri (EV_JOB_LOAD (ev_window->priv->load_job),
1980 ev_window->priv->local_uri);
1983 ev_window_reset_progress_cancellable (ev_window);
1985 target_file = g_file_new_for_uri (ev_window->priv->local_uri);
1986 g_file_copy_async (source_file, target_file,
1987 G_FILE_COPY_OVERWRITE,
1989 ev_window->priv->progress_cancellable,
1990 (GFileProgressCallback)window_open_file_copy_progress_cb,
1992 (GAsyncReadyCallback)window_open_file_copy_ready_cb,
1994 g_object_unref (target_file);
1996 ev_window_show_progress_message (ev_window, 1,
1997 (GSourceFunc)show_loading_progress);
2001 ev_window_open_uri (EvWindow *ev_window,
2004 EvWindowRunMode mode,
2005 const gchar *search_string)
2009 ev_window->priv->in_reload = FALSE;
2011 if (ev_window->priv->uri &&
2012 g_ascii_strcasecmp (ev_window->priv->uri, uri) == 0) {
2013 ev_window_reload_document (ev_window, dest);
2017 if (ev_window->priv->monitor) {
2018 g_object_unref (ev_window->priv->monitor);
2019 ev_window->priv->monitor = NULL;
2022 ev_window_close_dialogs (ev_window);
2023 ev_window_clear_load_job (ev_window);
2024 ev_window_clear_local_uri (ev_window);
2026 ev_window->priv->window_mode = mode;
2028 if (ev_window->priv->uri)
2029 g_free (ev_window->priv->uri);
2030 ev_window->priv->uri = g_strdup (uri);
2032 if (ev_window->priv->metadata)
2033 g_object_unref (ev_window->priv->metadata);
2034 if (ev_window->priv->bookmarks)
2035 g_object_unref (ev_window->priv->bookmarks);
2037 source_file = g_file_new_for_uri (uri);
2038 if (!ev_file_is_temp (source_file) && ev_is_metadata_supported_for_file (source_file)) {
2039 ev_window->priv->metadata = ev_metadata_new (source_file);
2040 ev_window->priv->is_new_doc = ev_metadata_is_empty (ev_window->priv->metadata);
2042 ev_window->priv->metadata = NULL;
2045 if (ev_window->priv->metadata) {
2046 ev_window->priv->bookmarks = ev_bookmarks_new (ev_window->priv->metadata);
2047 g_signal_connect_swapped (ev_window->priv->bookmarks, "changed",
2048 G_CALLBACK (ev_window_setup_bookmarks),
2051 ev_window->priv->bookmarks = NULL;
2054 if (ev_window->priv->search_string)
2055 g_free (ev_window->priv->search_string);
2056 ev_window->priv->search_string = search_string ?
2057 g_strdup (search_string) : NULL;
2059 if (ev_window->priv->dest)
2060 g_object_unref (ev_window->priv->dest);
2061 ev_window->priv->dest = dest ? g_object_ref (dest) : NULL;
2063 setup_size_from_metadata (ev_window);
2064 setup_model_from_metadata (ev_window);
2065 ev_window_setup_bookmarks (ev_window);
2067 ev_window->priv->load_job = ev_job_load_new (uri);
2068 g_signal_connect (ev_window->priv->load_job,
2070 G_CALLBACK (ev_window_load_job_cb),
2073 if (!g_file_is_native (source_file) && !ev_window->priv->local_uri) {
2074 ev_window_load_file_remote (ev_window, source_file);
2076 ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE);
2077 g_object_unref (source_file);
2078 ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
2083 ev_window_open_document (EvWindow *ev_window,
2084 EvDocument *document,
2086 EvWindowRunMode mode,
2087 const gchar *search_string)
2089 if (document == ev_window->priv->document)
2092 ev_window_close_dialogs (ev_window);
2093 ev_window_clear_load_job (ev_window);
2094 ev_window_clear_local_uri (ev_window);
2096 if (ev_window->priv->monitor) {
2097 g_object_unref (ev_window->priv->monitor);
2098 ev_window->priv->monitor = NULL;
2101 if (ev_window->priv->uri)
2102 g_free (ev_window->priv->uri);
2103 ev_window->priv->uri = g_strdup (ev_document_get_uri (document));
2105 setup_size_from_metadata (ev_window);
2106 setup_model_from_metadata (ev_window);
2108 ev_document_model_set_document (ev_window->priv->model, document);
2110 setup_document_from_metadata (ev_window);
2111 setup_view_from_metadata (ev_window);
2115 EvLinkAction *link_action;
2117 link_action = ev_link_action_new_dest (dest);
2118 link = ev_link_new (NULL, link_action);
2119 ev_view_handle_link (EV_VIEW (ev_window->priv->view), link);
2120 /* FIXME: link action should inc dest ref counting
2121 * or not unref it at all
2123 g_object_ref (dest);
2124 g_object_unref (link);
2128 case EV_WINDOW_MODE_FULLSCREEN:
2129 ev_window_run_fullscreen (ev_window);
2131 case EV_WINDOW_MODE_PRESENTATION:
2132 ev_window_run_presentation (ev_window);
2138 if (search_string && EV_IS_DOCUMENT_FIND (document)) {
2139 ev_window_cmd_edit_find (NULL, ev_window);
2140 egg_find_bar_set_search_string (EGG_FIND_BAR (ev_window->priv->find_bar),
2144 /* Create a monitor for the document */
2145 ev_window->priv->monitor = ev_file_monitor_new (ev_window->priv->uri);
2146 g_signal_connect_swapped (ev_window->priv->monitor, "changed",
2147 G_CALLBACK (ev_window_document_changed),
2152 ev_window_reload_local (EvWindow *ev_window)
2156 uri = ev_window->priv->local_uri ? ev_window->priv->local_uri : ev_window->priv->uri;
2157 ev_window->priv->reload_job = ev_job_load_new (uri);
2158 g_signal_connect (ev_window->priv->reload_job, "finished",
2159 G_CALLBACK (ev_window_reload_job_cb),
2161 ev_job_scheduler_push_job (ev_window->priv->reload_job, EV_JOB_PRIORITY_NONE);
2165 show_reloading_progress (EvWindow *ev_window)
2170 if (ev_window->priv->message_area)
2173 text = g_strdup_printf (_("Reloading document from %s"),
2174 ev_window->priv->uri);
2175 area = ev_progress_message_area_new (GTK_STOCK_REFRESH,
2180 GTK_RESPONSE_CANCEL,
2182 g_signal_connect (area, "response",
2183 G_CALLBACK (ev_window_progress_response_cb),
2185 gtk_widget_show (area);
2186 ev_window_set_message_area (ev_window, area);
2193 reload_remote_copy_ready_cb (GFile *remote,
2194 GAsyncResult *async_result,
2195 EvWindow *ev_window)
2197 GError *error = NULL;
2199 ev_window_clear_progress_idle (ev_window);
2201 g_file_copy_finish (remote, async_result, &error);
2203 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
2204 ev_window_error_message (ev_window, error,
2205 "%s", _("Failed to reload document."));
2206 g_error_free (error);
2208 ev_window_reload_local (ev_window);
2211 g_object_unref (remote);
2215 reload_remote_copy_progress_cb (goffset n_bytes,
2216 goffset total_bytes,
2217 EvWindow *ev_window)
2222 if (!ev_window->priv->message_area)
2225 if (total_bytes <= 0)
2228 fraction = n_bytes / (gdouble)total_bytes;
2229 status = g_strdup_printf (_("Downloading document (%d%%)"),
2230 (gint)(fraction * 100));
2232 ev_progress_message_area_set_status (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
2234 ev_progress_message_area_set_fraction (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
2241 query_remote_uri_mtime_cb (GFile *remote,
2242 GAsyncResult *async_result,
2243 EvWindow *ev_window)
2247 GError *error = NULL;
2249 info = g_file_query_info_finish (remote, async_result, &error);
2251 g_error_free (error);
2252 g_object_unref (remote);
2253 ev_window_reload_local (ev_window);
2258 g_file_info_get_modification_time (info, &mtime);
2259 if (ev_window->priv->uri_mtime != mtime.tv_sec) {
2262 /* Remote file has changed */
2263 ev_window->priv->uri_mtime = mtime.tv_sec;
2265 ev_window_reset_progress_cancellable (ev_window);
2267 target_file = g_file_new_for_uri (ev_window->priv->local_uri);
2268 g_file_copy_async (remote, target_file,
2269 G_FILE_COPY_OVERWRITE,
2271 ev_window->priv->progress_cancellable,
2272 (GFileProgressCallback)reload_remote_copy_progress_cb,
2274 (GAsyncReadyCallback)reload_remote_copy_ready_cb,
2276 g_object_unref (target_file);
2277 ev_window_show_progress_message (ev_window, 1,
2278 (GSourceFunc)show_reloading_progress);
2280 g_object_unref (remote);
2281 ev_window_reload_local (ev_window);
2284 g_object_unref (info);
2288 ev_window_reload_remote (EvWindow *ev_window)
2292 remote = g_file_new_for_uri (ev_window->priv->uri);
2293 /* Reload the remote uri only if it has changed */
2294 g_file_query_info_async (remote,
2295 G_FILE_ATTRIBUTE_TIME_MODIFIED,
2296 0, G_PRIORITY_DEFAULT,
2298 (GAsyncReadyCallback)query_remote_uri_mtime_cb,
2303 ev_window_reload_document (EvWindow *ev_window,
2309 ev_window_clear_reload_job (ev_window);
2310 ev_window->priv->in_reload = TRUE;
2312 page = ev_document_model_get_page (ev_window->priv->model);
2314 if (ev_window->priv->dest)
2315 g_object_unref (ev_window->priv->dest);
2316 ev_window->priv->dest = dest ? g_object_ref (dest) : NULL;
2318 if (ev_window->priv->local_uri) {
2319 ev_window_reload_remote (ev_window);
2321 ev_window_reload_local (ev_window);
2326 file_open_dialog_response_cb (GtkWidget *chooser,
2328 EvWindow *ev_window)
2330 if (response_id == GTK_RESPONSE_OK) {
2334 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (chooser));
2336 ev_application_open_uri_list (EV_APP, uris,
2337 gtk_window_get_screen (GTK_WINDOW (ev_window)),
2338 gtk_get_current_event_time ());
2340 g_slist_foreach (uris, (GFunc)g_free, NULL);
2341 g_slist_free (uris);
2343 uri = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (chooser));
2344 ev_application_set_filechooser_uri (EV_APP,
2345 GTK_FILE_CHOOSER_ACTION_OPEN,
2350 gtk_widget_destroy (chooser);
2354 ev_window_cmd_file_open (GtkAction *action, EvWindow *window)
2357 const gchar *default_uri;
2358 gchar *parent_uri = NULL;
2360 chooser = gtk_file_chooser_dialog_new (_("Open Document"),
2361 GTK_WINDOW (window),
2362 GTK_FILE_CHOOSER_ACTION_OPEN,
2364 GTK_RESPONSE_CANCEL,
2365 GTK_STOCK_OPEN, GTK_RESPONSE_OK,
2368 ev_document_factory_add_filters (chooser, NULL);
2369 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser), TRUE);
2370 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), FALSE);
2372 default_uri = ev_application_get_filechooser_uri (EV_APP, GTK_FILE_CHOOSER_ACTION_OPEN);
2373 if (!default_uri && window->priv->uri) {
2374 GFile *file, *parent;
2376 file = g_file_new_for_uri (window->priv->uri);
2377 parent = g_file_get_parent (file);
2379 parent_uri = g_file_get_uri (parent);
2380 default_uri = parent_uri;
2381 g_object_unref (parent);
2383 g_object_unref (file);
2387 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (chooser), default_uri);
2389 const gchar *folder;
2391 folder = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
2392 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
2393 folder ? folder : g_get_home_dir ());
2395 g_free (parent_uri);
2397 g_signal_connect (chooser, "response",
2398 G_CALLBACK (file_open_dialog_response_cb),
2401 gtk_widget_show (chooser);
2405 ev_window_open_copy_at_dest (EvWindow *window,
2408 EvWindow *new_window = EV_WINDOW (ev_window_new ());
2410 ev_window_n_copies++;
2412 if (window->priv->metadata)
2413 new_window->priv->metadata = g_object_ref (window->priv->metadata);
2414 ev_window_open_document (new_window,
2415 window->priv->document,
2417 gtk_window_present (GTK_WINDOW (new_window));
2421 ev_window_cmd_file_open_copy (GtkAction *action, EvWindow *window)
2423 ev_window_open_copy_at_dest (window, NULL);
2427 ev_window_cmd_recent_file_activate (GtkAction *action,
2430 GtkRecentInfo *info;
2433 info = g_object_get_data (G_OBJECT (action), "gtk-recent-info");
2434 g_assert (info != NULL);
2436 uri = gtk_recent_info_get_uri (info);
2438 ev_application_open_uri_at_dest (EV_APP, uri,
2439 gtk_window_get_screen (GTK_WINDOW (window)),
2440 NULL, 0, NULL, gtk_get_current_event_time ());
2444 ev_window_open_recent_action_item_activated (EvOpenRecentAction *action,
2448 ev_application_open_uri_at_dest (EV_APP, uri,
2449 gtk_window_get_screen (GTK_WINDOW (window)),
2450 NULL, 0, NULL, gtk_get_current_event_time ());
2454 ev_window_add_recent (EvWindow *window, const char *filename)
2456 gtk_recent_manager_add_item (window->priv->recent_manager, filename);
2460 compare_recent_items (GtkRecentInfo *a, GtkRecentInfo *b)
2462 gboolean has_ev_a, has_ev_b;
2463 const gchar *evince = g_get_application_name ();
2465 has_ev_a = gtk_recent_info_has_application (a, evince);
2466 has_ev_b = gtk_recent_info_has_application (b, evince);
2468 if (has_ev_a && has_ev_b) {
2469 time_t time_a, time_b;
2471 time_a = gtk_recent_info_get_modified (a);
2472 time_b = gtk_recent_info_get_modified (b);
2474 return (time_b - time_a);
2475 } else if (has_ev_a) {
2477 } else if (has_ev_b) {
2485 * Doubles underscore to avoid spurious menu accels.
2488 ev_window_get_recent_file_label (gint index, const gchar *filename)
2496 is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
2498 g_return_val_if_fail (filename != NULL, NULL);
2500 length = strlen (filename);
2501 str = g_string_sized_new (length + 10);
2502 g_string_printf (str, "%s_%d. ", is_rtl ? "\xE2\x80\x8F" : "", index);
2505 end = filename + length;
2509 next = g_utf8_next_char (p);
2513 g_string_append (str, "__");
2516 g_string_append_len (str, p, next - p);
2523 return g_string_free (str, FALSE);
2527 ev_window_recent_action_connect_proxy_cb (GtkActionGroup *action_group,
2534 if (!GTK_IS_MENU_ITEM (proxy))
2537 label = GTK_LABEL (gtk_bin_get_child (GTK_BIN (proxy)));
2539 gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_MIDDLE);
2540 gtk_label_set_max_width_chars (label, MAX_RECENT_ITEM_LEN);
2544 ev_window_setup_recent (EvWindow *ev_window)
2548 const gchar *evince = g_get_application_name ();
2551 if (ev_window->priv->recent_ui_id > 0) {
2552 gtk_ui_manager_remove_ui (ev_window->priv->ui_manager,
2553 ev_window->priv->recent_ui_id);
2554 gtk_ui_manager_ensure_update (ev_window->priv->ui_manager);
2556 ev_window->priv->recent_ui_id = gtk_ui_manager_new_merge_id (ev_window->priv->ui_manager);
2558 if (ev_window->priv->recent_action_group) {
2559 gtk_ui_manager_remove_action_group (ev_window->priv->ui_manager,
2560 ev_window->priv->recent_action_group);
2561 g_object_unref (ev_window->priv->recent_action_group);
2563 ev_window->priv->recent_action_group = gtk_action_group_new ("RecentFilesActions");
2564 g_signal_connect (ev_window->priv->recent_action_group, "connect-proxy",
2565 G_CALLBACK (ev_window_recent_action_connect_proxy_cb), NULL);
2567 gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
2568 ev_window->priv->recent_action_group, -1);
2570 items = gtk_recent_manager_get_items (ev_window->priv->recent_manager);
2571 items = g_list_sort (items, (GCompareFunc) compare_recent_items);
2573 for (l = items; l && l->data; l = g_list_next (l)) {
2574 GtkRecentInfo *info;
2578 const gchar *mime_type;
2579 gchar *content_type;
2582 info = (GtkRecentInfo *) l->data;
2584 if (!gtk_recent_info_has_application (info, evince) ||
2585 (gtk_recent_info_is_local (info) && !gtk_recent_info_exists (info)))
2588 action_name = g_strdup_printf ("RecentFile%u", i++);
2589 label = ev_window_get_recent_file_label (
2590 n_items + 1, gtk_recent_info_get_display_name (info));
2592 mime_type = gtk_recent_info_get_mime_type (info);
2593 content_type = g_content_type_from_mime_type (mime_type);
2594 if (content_type != NULL) {
2595 icon = g_content_type_get_icon (content_type);
2596 g_free (content_type);
2599 action = g_object_new (GTK_TYPE_ACTION,
2600 "name", action_name,
2603 "always-show-image", TRUE,
2606 g_object_set_data_full (G_OBJECT (action),
2608 gtk_recent_info_ref (info),
2609 (GDestroyNotify) gtk_recent_info_unref);
2611 g_signal_connect (action, "activate",
2612 G_CALLBACK (ev_window_cmd_recent_file_activate),
2613 (gpointer) ev_window);
2615 gtk_action_group_add_action (ev_window->priv->recent_action_group,
2617 g_object_unref (action);
2619 gtk_ui_manager_add_ui (ev_window->priv->ui_manager,
2620 ev_window->priv->recent_ui_id,
2621 "/MainMenu/FileMenu/RecentFilesMenu",
2624 GTK_UI_MANAGER_MENUITEM,
2626 g_free (action_name);
2629 g_object_unref (icon);
2635 g_list_foreach (items, (GFunc) gtk_recent_info_unref, NULL);
2636 g_list_free (items);
2640 show_saving_progress (GFile *dst)
2642 EvWindow *ev_window;
2646 EvSaveType save_type;
2648 ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window"));
2649 ev_window->priv->progress_idle = 0;
2651 if (ev_window->priv->message_area)
2654 save_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dst), "save-type"));
2655 uri = g_file_get_uri (dst);
2656 switch (save_type) {
2657 case EV_SAVE_DOCUMENT:
2658 text = g_strdup_printf (_("Saving document to %s"), uri);
2660 case EV_SAVE_ATTACHMENT:
2661 text = g_strdup_printf (_("Saving attachment to %s"), uri);
2664 text = g_strdup_printf (_("Saving image to %s"), uri);
2667 g_assert_not_reached ();
2670 area = ev_progress_message_area_new (GTK_STOCK_SAVE,
2675 GTK_RESPONSE_CANCEL,
2677 g_signal_connect (area, "response",
2678 G_CALLBACK (ev_window_progress_response_cb),
2680 gtk_widget_show (area);
2681 ev_window_set_message_area (ev_window, area);
2688 window_save_file_copy_ready_cb (GFile *src,
2689 GAsyncResult *async_result,
2692 EvWindow *ev_window;
2693 GError *error = NULL;
2695 ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window"));
2696 ev_window_clear_progress_idle (ev_window);
2698 if (g_file_copy_finish (src, async_result, &error)) {
2699 ev_tmp_file_unlink (src);
2703 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
2706 name = g_file_get_basename (dst);
2707 ev_window_error_message (ev_window, error,
2708 _("The file could not be saved as “%s”."),
2712 ev_tmp_file_unlink (src);
2713 g_error_free (error);
2717 window_save_file_copy_progress_cb (goffset n_bytes,
2718 goffset total_bytes,
2721 EvWindow *ev_window;
2722 EvSaveType save_type;
2726 ev_window = EV_WINDOW (g_object_get_data (G_OBJECT (dst), "ev-window"));
2728 if (!ev_window->priv->message_area)
2731 if (total_bytes <= 0)
2734 fraction = n_bytes / (gdouble)total_bytes;
2735 save_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dst), "save-type"));
2737 switch (save_type) {
2738 case EV_SAVE_DOCUMENT:
2739 status = g_strdup_printf (_("Uploading document (%d%%)"),
2740 (gint)(fraction * 100));
2742 case EV_SAVE_ATTACHMENT:
2743 status = g_strdup_printf (_("Uploading attachment (%d%%)"),
2744 (gint)(fraction * 100));
2747 status = g_strdup_printf (_("Uploading image (%d%%)"),
2748 (gint)(fraction * 100));
2751 g_assert_not_reached ();
2754 ev_progress_message_area_set_status (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
2756 ev_progress_message_area_set_fraction (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
2763 ev_window_save_remote (EvWindow *ev_window,
2764 EvSaveType save_type,
2768 ev_window_reset_progress_cancellable (ev_window);
2769 g_object_set_data (G_OBJECT (dst), "ev-window", ev_window);
2770 g_object_set_data (G_OBJECT (dst), "save-type", GINT_TO_POINTER (save_type));
2771 g_file_copy_async (src, dst,
2772 G_FILE_COPY_OVERWRITE,
2774 ev_window->priv->progress_cancellable,
2775 (GFileProgressCallback)window_save_file_copy_progress_cb,
2777 (GAsyncReadyCallback)window_save_file_copy_ready_cb,
2779 ev_window->priv->progress_idle =
2780 g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
2782 (GSourceFunc)show_saving_progress,
2788 ev_window_clear_save_job (EvWindow *ev_window)
2790 if (ev_window->priv->save_job != NULL) {
2791 if (!ev_job_is_finished (ev_window->priv->save_job))
2792 ev_job_cancel (ev_window->priv->save_job);
2794 g_signal_handlers_disconnect_by_func (ev_window->priv->save_job,
2795 ev_window_save_job_cb,
2797 g_object_unref (ev_window->priv->save_job);
2798 ev_window->priv->save_job = NULL;
2803 ev_window_save_job_cb (EvJob *job,
2806 if (ev_job_is_failed (job)) {
2807 ev_window_error_message (window, job->error,
2808 _("The file could not be saved as “%s”."),
2809 EV_JOB_SAVE (job)->uri);
2811 ev_window_add_recent (window, EV_JOB_SAVE (job)->uri);
2814 ev_window_clear_save_job (window);
2818 file_save_dialog_response_cb (GtkWidget *fc,
2820 EvWindow *ev_window)
2823 GFile *file, *parent;
2825 if (response_id != GTK_RESPONSE_OK) {
2826 gtk_widget_destroy (fc);
2830 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
2831 file = g_file_new_for_uri (uri);
2832 parent = g_file_get_parent (file);
2833 g_object_unref (file);
2837 folder_uri = g_file_get_uri (parent);
2838 ev_application_set_filechooser_uri (EV_APP,
2839 GTK_FILE_CHOOSER_ACTION_SAVE,
2841 g_free (folder_uri);
2842 g_object_unref (parent);
2845 /* FIXME: remote copy should be done here rather than in the save job,
2846 * so that we can track progress and cancel the operation
2849 ev_window_clear_save_job (ev_window);
2850 ev_window->priv->save_job = ev_job_save_new (ev_window->priv->document,
2851 uri, ev_window->priv->uri);
2852 g_signal_connect (ev_window->priv->save_job, "finished",
2853 G_CALLBACK (ev_window_save_job_cb),
2855 /* The priority doesn't matter for this job */
2856 ev_job_scheduler_push_job (ev_window->priv->save_job, EV_JOB_PRIORITY_NONE);
2859 gtk_widget_destroy (fc);
2863 ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window)
2868 const gchar *default_uri;
2870 fc = gtk_file_chooser_dialog_new (
2872 GTK_WINDOW (ev_window), GTK_FILE_CHOOSER_ACTION_SAVE,
2873 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
2874 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
2877 ev_document_factory_add_filters (fc, ev_window->priv->document);
2878 gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK);
2879 gtk_dialog_set_alternative_button_order (GTK_DIALOG (fc),
2881 GTK_RESPONSE_CANCEL,
2884 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (fc), FALSE);
2885 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE);
2886 file = g_file_new_for_uri (ev_window->priv->uri);
2887 base_name = g_file_get_basename (file);
2888 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (fc), base_name);
2890 default_uri = ev_application_get_filechooser_uri (EV_APP, GTK_FILE_CHOOSER_ACTION_SAVE);
2892 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (fc), default_uri);
2894 const gchar *folder;
2896 folder = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
2897 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (fc),
2898 folder ? folder : g_get_home_dir ());
2901 g_object_unref (file);
2904 g_signal_connect (fc, "response",
2905 G_CALLBACK (file_save_dialog_response_cb),
2908 gtk_widget_show (fc);
2912 ev_window_cmd_open_containing_folder (GtkAction *action, EvWindow *ev_window)
2914 GtkWidget *ev_window_widget;
2918 ev_window_widget = GTK_WIDGET (ev_window);
2920 file = g_file_new_for_uri (ev_window->priv->uri);
2921 parent = g_file_get_parent (file);
2926 parent_uri = g_file_get_uri (parent);
2932 screen = gtk_widget_get_screen (ev_window_widget);
2933 timestamp = gtk_get_current_event_time ();
2936 if (!gtk_show_uri (screen, parent_uri, timestamp, &error)) {
2937 ev_window_error_message (ev_window, error, _("Could not open the containing folder"));
2938 g_error_free (error);
2941 g_free (parent_uri);
2946 g_object_unref (file);
2949 g_object_unref (parent);
2954 get_print_settings_file (void)
2956 GKeyFile *print_settings_file;
2958 GError *error = NULL;
2960 print_settings_file = g_key_file_new ();
2962 filename = g_build_filename (ev_application_get_dot_dir (EV_APP, FALSE),
2963 EV_PRINT_SETTINGS_FILE, NULL);
2964 if (!g_key_file_load_from_file (print_settings_file,
2966 G_KEY_FILE_KEEP_COMMENTS |
2967 G_KEY_FILE_KEEP_TRANSLATIONS,
2970 /* Don't warn if the file simply doesn't exist */
2971 if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
2972 g_warning ("%s", error->message);
2974 g_error_free (error);
2979 return print_settings_file;
2983 save_print_setting_file (GKeyFile *key_file)
2988 GError *error = NULL;
2990 filename = g_build_filename (ev_application_get_dot_dir (EV_APP, TRUE),
2991 EV_PRINT_SETTINGS_FILE, NULL);
2992 data = g_key_file_to_data (key_file, &data_length, NULL);
2993 g_file_set_contents (filename, data, data_length, &error);
2995 g_warning ("Failed to save print settings: %s", error->message);
2996 g_error_free (error);
3003 ev_window_save_print_settings (EvWindow *window,
3004 GtkPrintSettings *print_settings)
3009 key_file = get_print_settings_file ();
3010 gtk_print_settings_to_key_file (print_settings, key_file, EV_PRINT_SETTINGS_GROUP);
3012 /* Save print settings that are specific to the document */
3013 for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) {
3014 /* Remove it from global settings */
3015 g_key_file_remove_key (key_file, EV_PRINT_SETTINGS_GROUP,
3016 document_print_settings[i], NULL);
3018 if (window->priv->metadata) {
3021 value = gtk_print_settings_get (print_settings,
3022 document_print_settings[i]);
3023 ev_metadata_set_string (window->priv->metadata,
3024 document_print_settings[i], value);
3028 save_print_setting_file (key_file);
3029 g_key_file_free (key_file);
3033 ev_window_save_print_page_setup (EvWindow *window,
3034 GtkPageSetup *page_setup)
3038 key_file = get_print_settings_file ();
3039 gtk_page_setup_to_key_file (page_setup, key_file, EV_PAGE_SETUP_GROUP);
3041 /* Do not save document settings in global file */
3042 g_key_file_remove_key (key_file, EV_PAGE_SETUP_GROUP,
3043 "page-setup-orientation", NULL);
3044 g_key_file_remove_key (key_file, EV_PAGE_SETUP_GROUP,
3045 "page-setup-margin-top", NULL);
3046 g_key_file_remove_key (key_file, EV_PAGE_SETUP_GROUP,
3047 "page-setup-margin-bottom", NULL);
3048 g_key_file_remove_key (key_file, EV_PAGE_SETUP_GROUP,
3049 "page-setup-margin-left", NULL);
3050 g_key_file_remove_key (key_file, EV_PAGE_SETUP_GROUP,
3051 "page-setup-margin-right", NULL);
3053 save_print_setting_file (key_file);
3054 g_key_file_free (key_file);
3056 if (!window->priv->metadata)
3059 /* Save page setup options that are specific to the document */
3060 ev_metadata_set_int (window->priv->metadata, "page-setup-orientation",
3061 gtk_page_setup_get_orientation (page_setup));
3062 ev_metadata_set_double (window->priv->metadata, "page-setup-margin-top",
3063 gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM));
3064 ev_metadata_set_double (window->priv->metadata, "page-setup-margin-bottom",
3065 gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM));
3066 ev_metadata_set_double (window->priv->metadata, "page-setup-margin-left",
3067 gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM));
3068 ev_metadata_set_double (window->priv->metadata, "page-setup-margin-right",
3069 gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM));
3073 ev_window_load_print_settings_from_metadata (EvWindow *window,
3074 GtkPrintSettings *print_settings)
3078 if (!window->priv->metadata)
3081 /* Load print setting that are specific to the document */
3082 for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) {
3083 gchar *value = NULL;
3085 ev_metadata_get_string (window->priv->metadata,
3086 document_print_settings[i], &value);
3087 gtk_print_settings_set (print_settings,
3088 document_print_settings[i], value);
3093 ev_window_load_print_page_setup_from_metadata (EvWindow *window,
3094 GtkPageSetup *page_setup)
3097 gdouble double_value;
3098 GtkPaperSize *paper_size = gtk_page_setup_get_paper_size (page_setup);
3100 /* Load page setup options that are specific to the document */
3101 if (window->priv->metadata &&
3102 ev_metadata_get_int (window->priv->metadata, "page-setup-orientation", &int_value)) {
3103 gtk_page_setup_set_orientation (page_setup, int_value);
3105 gtk_page_setup_set_orientation (page_setup, GTK_PAGE_ORIENTATION_PORTRAIT);
3108 if (window->priv->metadata &&
3109 ev_metadata_get_double (window->priv->metadata, "page-setup-margin-top", &double_value)) {
3110 gtk_page_setup_set_top_margin (page_setup, double_value, GTK_UNIT_MM);
3112 gtk_page_setup_set_top_margin (page_setup,
3113 gtk_paper_size_get_default_top_margin (paper_size, GTK_UNIT_MM),
3117 if (window->priv->metadata &&
3118 ev_metadata_get_double (window->priv->metadata, "page-setup-margin-bottom", &double_value)) {
3119 gtk_page_setup_set_bottom_margin (page_setup, double_value, GTK_UNIT_MM);
3121 gtk_page_setup_set_bottom_margin (page_setup,
3122 gtk_paper_size_get_default_bottom_margin (paper_size, GTK_UNIT_MM),
3126 if (window->priv->metadata &&
3127 ev_metadata_get_double (window->priv->metadata, "page-setup-margin-left", &double_value)) {
3128 gtk_page_setup_set_left_margin (page_setup, double_value, GTK_UNIT_MM);
3130 gtk_page_setup_set_left_margin (page_setup,
3131 gtk_paper_size_get_default_left_margin (paper_size, GTK_UNIT_MM),
3135 if (window->priv->metadata &&
3136 ev_metadata_get_double (window->priv->metadata, "page-setup-margin-right", &double_value)) {
3137 gtk_page_setup_set_right_margin (page_setup, double_value, GTK_UNIT_MM);
3139 gtk_page_setup_set_right_margin (page_setup,
3140 gtk_paper_size_get_default_right_margin (paper_size, GTK_UNIT_MM),
3145 static GtkPrintSettings *
3146 get_print_settings (GKeyFile *key_file)
3148 GtkPrintSettings *print_settings;
3150 print_settings = g_key_file_has_group (key_file, EV_PRINT_SETTINGS_GROUP) ?
3151 gtk_print_settings_new_from_key_file (key_file, EV_PRINT_SETTINGS_GROUP, NULL) :
3152 gtk_print_settings_new ();
3154 return print_settings ? print_settings : gtk_print_settings_new ();
3157 static GtkPageSetup *
3158 get_print_page_setup (GKeyFile *key_file)
3160 GtkPageSetup *page_setup;
3162 page_setup = g_key_file_has_group (key_file, EV_PAGE_SETUP_GROUP) ?
3163 gtk_page_setup_new_from_key_file (key_file, EV_PAGE_SETUP_GROUP, NULL) :
3164 gtk_page_setup_new ();
3166 return page_setup ? page_setup : gtk_page_setup_new ();
3170 ev_window_print_cancel (EvWindow *ev_window)
3172 EvPrintOperation *op;
3174 if (!ev_window->priv->print_queue)
3177 while ((op = g_queue_peek_tail (ev_window->priv->print_queue))) {
3178 ev_print_operation_cancel (op);
3183 ev_window_print_update_pending_jobs_message (EvWindow *ev_window,
3188 if (!EV_IS_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area) ||
3189 !ev_window->priv->print_queue)
3193 ev_window_set_message_area (ev_window, NULL);
3198 text = g_strdup_printf (ngettext ("%d pending job in queue",
3199 "%d pending jobs in queue",
3200 n_jobs - 1), n_jobs - 1);
3203 ev_message_area_set_secondary_text (EV_MESSAGE_AREA (ev_window->priv->message_area),
3209 destroy_window (GtkWidget *window)
3211 gtk_widget_destroy (window);
3217 ev_window_print_operation_done (EvPrintOperation *op,
3218 GtkPrintOperationResult result,
3219 EvWindow *ev_window)
3224 case GTK_PRINT_OPERATION_RESULT_APPLY: {
3225 GtkPrintSettings *print_settings;
3227 print_settings = ev_print_operation_get_print_settings (op);
3228 ev_window_save_print_settings (ev_window, print_settings);
3230 if (ev_print_operation_get_embed_page_setup (op)) {
3231 GtkPageSetup *page_setup;
3233 page_setup = ev_print_operation_get_default_page_setup (op);
3234 ev_window_save_print_page_setup (ev_window, page_setup);
3239 case GTK_PRINT_OPERATION_RESULT_ERROR: {
3241 GError *error = NULL;
3244 ev_print_operation_get_error (op, &error);
3246 /* The message area is already used by
3247 * the printing progress, so it's better to
3248 * use a popup dialog in this case
3250 dialog = gtk_message_dialog_new (GTK_WINDOW (ev_window),
3251 GTK_DIALOG_DESTROY_WITH_PARENT,
3254 "%s", _("Failed to print document"));
3255 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
3256 "%s", error->message);
3257 g_signal_connect (dialog, "response",
3258 G_CALLBACK (gtk_widget_destroy),
3260 gtk_widget_show (dialog);
3262 g_error_free (error);
3265 case GTK_PRINT_OPERATION_RESULT_CANCEL:
3270 g_queue_remove (ev_window->priv->print_queue, op);
3271 g_object_unref (op);
3272 n_jobs = g_queue_get_length (ev_window->priv->print_queue);
3273 ev_window_print_update_pending_jobs_message (ev_window, n_jobs);
3275 if (n_jobs == 0 && ev_window->priv->close_after_print)
3276 g_idle_add ((GSourceFunc)destroy_window,
3281 ev_window_print_progress_response_cb (EvProgressMessageArea *area,
3283 EvWindow *ev_window)
3285 if (response == GTK_RESPONSE_CANCEL) {
3286 EvPrintOperation *op;
3288 op = g_queue_peek_tail (ev_window->priv->print_queue);
3289 ev_print_operation_cancel (op);
3291 gtk_widget_hide (GTK_WIDGET (area));
3296 ev_window_print_operation_status_changed (EvPrintOperation *op,
3297 EvWindow *ev_window)
3299 const gchar *status;
3302 status = ev_print_operation_get_status (op);
3303 fraction = ev_print_operation_get_progress (op);
3305 if (!ev_window->priv->message_area) {
3307 const gchar *job_name;
3310 job_name = ev_print_operation_get_job_name (op);
3311 text = g_strdup_printf (_("Printing job “%s”"), job_name);
3313 area = ev_progress_message_area_new (GTK_STOCK_PRINT,
3318 GTK_RESPONSE_CANCEL,
3320 ev_window_print_update_pending_jobs_message (ev_window, 1);
3321 g_signal_connect (area, "response",
3322 G_CALLBACK (ev_window_print_progress_response_cb),
3324 gtk_widget_show (area);
3325 ev_window_set_message_area (ev_window, area);
3329 ev_progress_message_area_set_status (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
3331 ev_progress_message_area_set_fraction (EV_PROGRESS_MESSAGE_AREA (ev_window->priv->message_area),
3336 ev_window_print_operation_begin_print (EvPrintOperation *op,
3337 EvWindow *ev_window)
3339 if (!ev_window->priv->print_queue)
3340 ev_window->priv->print_queue = g_queue_new ();
3342 g_queue_push_head (ev_window->priv->print_queue, op);
3343 ev_window_print_update_pending_jobs_message (ev_window,
3344 g_queue_get_length (ev_window->priv->print_queue));
3348 ev_window_print_range (EvWindow *ev_window,
3352 EvPrintOperation *op;
3353 GKeyFile *print_settings_file;
3354 GtkPrintSettings *print_settings;
3355 GtkPageSetup *print_page_setup;
3357 gint document_last_page;
3358 gboolean embed_page_setup;
3360 g_return_if_fail (EV_IS_WINDOW (ev_window));
3361 g_return_if_fail (ev_window->priv->document != NULL);
3363 if (!ev_window->priv->print_queue)
3364 ev_window->priv->print_queue = g_queue_new ();
3366 op = ev_print_operation_new (ev_window->priv->document);
3368 g_warning ("%s", "Printing is not supported for document\n");
3372 g_signal_connect (op, "begin_print",
3373 G_CALLBACK (ev_window_print_operation_begin_print),
3374 (gpointer)ev_window);
3375 g_signal_connect (op, "status_changed",
3376 G_CALLBACK (ev_window_print_operation_status_changed),
3377 (gpointer)ev_window);
3378 g_signal_connect (op, "done",
3379 G_CALLBACK (ev_window_print_operation_done),
3380 (gpointer)ev_window);
3382 current_page = ev_document_model_get_page (ev_window->priv->model);
3383 document_last_page = ev_document_get_n_pages (ev_window->priv->document);
3385 print_settings_file = get_print_settings_file ();
3387 print_settings = get_print_settings (print_settings_file);
3388 ev_window_load_print_settings_from_metadata (ev_window, print_settings);
3390 print_page_setup = get_print_page_setup (print_settings_file);
3391 ev_window_load_print_page_setup_from_metadata (ev_window, print_page_setup);
3393 if (first_page != 1 || last_page != document_last_page) {
3396 /* Ranges in GtkPrint are 0 - N */
3397 range.start = first_page - 1;
3398 range.end = last_page - 1;
3400 gtk_print_settings_set_print_pages (print_settings,
3401 GTK_PRINT_PAGES_RANGES);
3402 gtk_print_settings_set_page_ranges (print_settings,
3406 ev_print_operation_set_job_name (op, gtk_window_get_title (GTK_WINDOW (ev_window)));
3407 ev_print_operation_set_current_page (op, current_page);
3408 ev_print_operation_set_print_settings (op, print_settings);
3409 ev_print_operation_set_default_page_setup (op, print_page_setup);
3410 embed_page_setup = ev_window->priv->lockdown_settings ?
3411 !g_settings_get_boolean (ev_window->priv->lockdown_settings,
3412 GS_LOCKDOWN_PRINT_SETUP) :
3414 ev_print_operation_set_embed_page_setup (op, embed_page_setup);
3416 g_object_unref (print_settings);
3417 g_object_unref (print_page_setup);
3418 g_key_file_free (print_settings_file);
3420 ev_print_operation_run (op, GTK_WINDOW (ev_window));
3424 ev_window_print (EvWindow *window)
3426 ev_window_print_range (window, 1,
3427 ev_document_get_n_pages (window->priv->document));
3431 ev_window_cmd_file_print (GtkAction *action, EvWindow *ev_window)
3433 ev_window_print (ev_window);
3437 ev_window_cmd_file_properties (GtkAction *action, EvWindow *ev_window)
3439 if (ev_window->priv->properties == NULL) {
3440 ev_window->priv->properties = ev_properties_dialog_new ();
3441 ev_properties_dialog_set_document (EV_PROPERTIES_DIALOG (ev_window->priv->properties),
3442 ev_window->priv->uri,
3443 ev_window->priv->document);
3444 g_object_add_weak_pointer (G_OBJECT (ev_window->priv->properties),
3445 (gpointer) &(ev_window->priv->properties));
3446 gtk_window_set_transient_for (GTK_WINDOW (ev_window->priv->properties),
3447 GTK_WINDOW (ev_window));
3450 ev_document_fc_mutex_lock ();
3451 gtk_widget_show (ev_window->priv->properties);
3452 ev_document_fc_mutex_unlock ();
3456 document_modified_confirmation_dialog_response (GtkDialog *dialog,
3458 EvWindow *ev_window)
3460 gtk_widget_destroy (GTK_WIDGET (dialog));
3463 case GTK_RESPONSE_YES:
3464 ev_window_cmd_save_as (NULL, ev_window);
3466 case GTK_RESPONSE_NO:
3467 gtk_widget_destroy (GTK_WIDGET (ev_window));
3469 case GTK_RESPONSE_CANCEL:
3476 ev_window_check_document_modified (EvWindow *ev_window)
3478 EvDocument *document = ev_window->priv->document;
3480 gchar *text, *markup;
3481 const gchar *secondary_text;
3486 if (EV_IS_DOCUMENT_FORMS (document) &&
3487 ev_document_forms_document_is_modified (EV_DOCUMENT_FORMS (document))) {
3488 secondary_text = _("Document contains form fields that have been filled out. "
3489 "If you don't save a copy, changes will be permanently lost.");
3490 } else if (EV_IS_DOCUMENT_ANNOTATIONS (document) &&
3491 ev_document_annotations_document_is_modified (EV_DOCUMENT_ANNOTATIONS (document))) {
3492 secondary_text = _("Document contains new or modified annotations. "
3493 "If you don't save a copy, changes will be permanently lost.");
3499 text = g_markup_printf_escaped (_("Save a copy of document “%s” before closing?"),
3500 gtk_window_get_title (GTK_WINDOW (ev_window)));
3502 dialog = gtk_message_dialog_new (GTK_WINDOW (ev_window),
3504 GTK_MESSAGE_QUESTION,
3508 markup = g_strdup_printf ("<b>%s</b>", text);
3511 gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), markup);
3514 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
3515 "%s", secondary_text);
3517 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
3518 _("Close _without Saving"),
3521 GTK_RESPONSE_CANCEL,
3525 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
3526 gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
3529 GTK_RESPONSE_CANCEL,
3532 g_signal_connect (dialog, "response",
3533 G_CALLBACK (document_modified_confirmation_dialog_response),
3535 gtk_widget_show (dialog);
3541 print_jobs_confirmation_dialog_response (GtkDialog *dialog,
3543 EvWindow *ev_window)
3545 gtk_widget_destroy (GTK_WIDGET (dialog));
3548 case GTK_RESPONSE_YES:
3549 if (!ev_window->priv->print_queue ||
3550 g_queue_is_empty (ev_window->priv->print_queue))
3551 gtk_widget_destroy (GTK_WIDGET (ev_window));
3553 ev_window->priv->close_after_print = TRUE;
3555 case GTK_RESPONSE_NO:
3556 ev_window->priv->close_after_print = TRUE;
3557 if (ev_window->priv->print_queue &&
3558 !g_queue_is_empty (ev_window->priv->print_queue)) {
3559 gtk_widget_set_sensitive (GTK_WIDGET (ev_window), FALSE);
3560 ev_window_print_cancel (ev_window);
3562 gtk_widget_destroy (GTK_WIDGET (ev_window));
3565 case GTK_RESPONSE_CANCEL:
3567 ev_window->priv->close_after_print = FALSE;
3572 ev_window_check_print_queue (EvWindow *ev_window)
3575 gchar *text, *markup;
3578 n_print_jobs = ev_window->priv->print_queue ?
3579 g_queue_get_length (ev_window->priv->print_queue) : 0;
3581 if (n_print_jobs == 0)
3584 dialog = gtk_message_dialog_new (GTK_WINDOW (ev_window),
3586 GTK_MESSAGE_QUESTION,
3589 if (n_print_jobs == 1) {
3590 EvPrintOperation *op;
3591 const gchar *job_name;
3593 op = g_queue_peek_tail (ev_window->priv->print_queue);
3594 job_name = ev_print_operation_get_job_name (op);
3596 text = g_strdup_printf (_("Wait until print job “%s” finishes before closing?"),
3599 text = g_strdup_printf (_("There are %d print jobs active. "
3600 "Wait until print finishes before closing?"),
3604 markup = g_strdup_printf ("<b>%s</b>", text);
3607 gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), markup);
3610 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s",
3611 _("If you close the window, pending print "
3612 "jobs will not be printed."));
3614 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
3615 _("Cancel _print and Close"),
3618 GTK_RESPONSE_CANCEL,
3619 _("Close _after Printing"),
3622 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
3623 gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
3626 GTK_RESPONSE_CANCEL,
3629 g_signal_connect (dialog, "response",
3630 G_CALLBACK (print_jobs_confirmation_dialog_response),
3632 gtk_widget_show (dialog);
3638 ev_window_close (EvWindow *ev_window)
3640 if (EV_WINDOW_IS_PRESENTATION (ev_window)) {
3643 /* Save current page */
3644 current_page = ev_view_presentation_get_current_page (
3645 EV_VIEW_PRESENTATION (ev_window->priv->presentation_view));
3646 ev_document_model_set_page (ev_window->priv->model, current_page);
3649 if (ev_window_check_document_modified (ev_window))
3652 if (ev_window_check_print_queue (ev_window))
3659 ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window)
3661 if (ev_window_close (ev_window))
3662 gtk_widget_destroy (GTK_WIDGET (ev_window));
3666 ev_window_cmd_focus_page_selector (GtkAction *act, EvWindow *window)
3670 update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, TRUE);
3671 ev_window_set_action_sensitive (window, "ViewToolbar", FALSE);
3672 update_chrome_visibility (window);
3674 action = gtk_action_group_get_action (window->priv->action_group,
3675 PAGE_SELECTOR_ACTION);
3676 ev_page_action_grab_focus (EV_PAGE_ACTION (action));
3680 ev_window_cmd_scroll_forward (GtkAction *action, EvWindow *window)
3682 ev_view_scroll (EV_VIEW (window->priv->view), GTK_SCROLL_PAGE_FORWARD, FALSE);
3686 ev_window_cmd_scroll_backward (GtkAction *action, EvWindow *window)
3688 ev_view_scroll (EV_VIEW (window->priv->view), GTK_SCROLL_PAGE_BACKWARD, FALSE);
3692 ev_window_cmd_continuous (GtkAction *action, EvWindow *ev_window)
3694 gboolean continuous;
3696 ev_window_stop_presentation (ev_window, TRUE);
3697 continuous = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
3698 ev_document_model_set_continuous (ev_window->priv->model, continuous);
3702 ev_window_cmd_dual (GtkAction *action, EvWindow *ev_window)
3706 ev_window_stop_presentation (ev_window, TRUE);
3707 dual_page = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
3708 ev_document_model_set_dual_page (ev_window->priv->model, dual_page);
3712 ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window)
3714 ev_window_stop_presentation (ev_window, TRUE);
3716 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
3717 ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_BEST_FIT);
3719 ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE);
3721 ev_window_update_actions (ev_window);
3725 ev_window_cmd_view_page_width (GtkAction *action, EvWindow *ev_window)
3727 ev_window_stop_presentation (ev_window, TRUE);
3729 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
3730 ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FIT_WIDTH);
3732 ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE);
3734 ev_window_update_actions (ev_window);
3739 ev_window_cmd_edit_select_all (GtkAction *action, EvWindow *ev_window)
3741 g_return_if_fail (EV_IS_WINDOW (ev_window));
3743 ev_view_select_all (EV_VIEW (ev_window->priv->view));
3747 ev_window_cmd_edit_find (GtkAction *action, EvWindow *ev_window)
3749 g_return_if_fail (EV_IS_WINDOW (ev_window));
3751 if (ev_window->priv->document == NULL || !EV_IS_DOCUMENT_FIND (ev_window->priv->document)) {
3752 g_error ("Find action should be insensitive since document doesn't support find");
3756 update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE);
3757 update_chrome_visibility (ev_window);
3758 gtk_widget_grab_focus (ev_window->priv->find_bar);
3762 ev_window_cmd_edit_find_next (GtkAction *action, EvWindow *ev_window)
3764 g_return_if_fail (EV_IS_WINDOW (ev_window));
3766 update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE);
3767 update_chrome_visibility (ev_window);
3768 gtk_widget_grab_focus (ev_window->priv->find_bar);
3769 ev_view_find_next (EV_VIEW (ev_window->priv->view));
3773 ev_window_cmd_edit_find_previous (GtkAction *action, EvWindow *ev_window)
3775 g_return_if_fail (EV_IS_WINDOW (ev_window));
3777 update_chrome_flag (ev_window, EV_CHROME_FINDBAR, TRUE);
3778 update_chrome_visibility (ev_window);
3779 gtk_widget_grab_focus (ev_window->priv->find_bar);
3780 ev_view_find_previous (EV_VIEW (ev_window->priv->view));
3784 ev_window_cmd_edit_copy (GtkAction *action, EvWindow *ev_window)
3786 g_return_if_fail (EV_IS_WINDOW (ev_window));
3788 ev_view_copy (EV_VIEW (ev_window->priv->view));
3792 ev_window_sidebar_position_change_cb (GObject *object,
3794 EvWindow *ev_window)
3796 if (ev_window->priv->metadata && !ev_window_is_empty (ev_window))
3797 ev_metadata_set_int (ev_window->priv->metadata, "sidebar_size",
3798 gtk_paned_get_position (GTK_PANED (object)));
3802 ev_window_update_fullscreen_action (EvWindow *window)
3806 action = gtk_action_group_get_action (window->priv->action_group, "ViewFullscreen");
3807 g_signal_handlers_block_by_func
3808 (action, G_CALLBACK (ev_window_cmd_view_fullscreen), window);
3809 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
3810 ev_document_model_get_fullscreen (window->priv->model));
3811 g_signal_handlers_unblock_by_func
3812 (action, G_CALLBACK (ev_window_cmd_view_fullscreen), window);
3816 fullscreen_toolbar_setup_item_properties (GtkUIManager *ui_manager)
3820 item = gtk_ui_manager_get_widget (ui_manager, "/FullscreenToolbar/GoPreviousPage");
3821 g_object_set (item, "is-important", FALSE, NULL);
3823 item = gtk_ui_manager_get_widget (ui_manager, "/FullscreenToolbar/GoNextPage");
3824 g_object_set (item, "is-important", FALSE, NULL);
3826 item = gtk_ui_manager_get_widget (ui_manager, "/FullscreenToolbar/StartPresentation");
3827 g_object_set (item, "is-important", TRUE, NULL);
3829 item = gtk_ui_manager_get_widget (ui_manager, "/FullscreenToolbar/LeaveFullscreen");
3830 g_object_set (item, "is-important", TRUE, NULL);
3834 fullscreen_toolbar_remove_shadow (GtkWidget *toolbar)
3836 static gboolean done = FALSE;
3839 gtk_rc_parse_string (
3841 " style \"fullscreen-toolbar-style\"\n"
3843 " GtkToolbar::shadow-type=GTK_SHADOW_NONE\n"
3846 " widget \"*.fullscreen-toolbar\" style \"fullscreen-toolbar-style\"\n"
3851 gtk_widget_set_name (toolbar, "fullscreen-toolbar");
3855 ev_window_run_fullscreen (EvWindow *window)
3857 gboolean fullscreen_window = TRUE;
3859 if (ev_document_model_get_fullscreen (window->priv->model))
3862 if (!window->priv->fullscreen_toolbar) {
3863 window->priv->fullscreen_toolbar =
3864 gtk_ui_manager_get_widget (window->priv->ui_manager,
3865 "/FullscreenToolbar");
3867 gtk_toolbar_set_style (GTK_TOOLBAR (window->priv->fullscreen_toolbar),
3868 GTK_TOOLBAR_BOTH_HORIZ);
3869 fullscreen_toolbar_remove_shadow (window->priv->fullscreen_toolbar);
3870 fullscreen_toolbar_setup_item_properties (window->priv->ui_manager);
3872 gtk_box_pack_start (GTK_BOX (window->priv->main_box),
3873 window->priv->fullscreen_toolbar,
3875 gtk_box_reorder_child (GTK_BOX (window->priv->main_box),
3876 window->priv->fullscreen_toolbar, 1);
3879 if (EV_WINDOW_IS_PRESENTATION (window)) {
3880 ev_window_stop_presentation (window, FALSE);
3881 fullscreen_window = FALSE;
3884 g_object_set (G_OBJECT (window->priv->scrolled_window),
3885 "shadow-type", GTK_SHADOW_NONE,
3888 ev_document_model_set_fullscreen (window->priv->model, TRUE);
3889 ev_window_update_fullscreen_action (window);
3891 /* If the user doesn't have the main toolbar he/she won't probably want
3892 * the toolbar in fullscreen mode. See bug #483048
3894 update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR,
3895 (window->priv->chrome & EV_CHROME_TOOLBAR) != 0);
3896 update_chrome_visibility (window);
3898 if (fullscreen_window)
3899 gtk_window_fullscreen (GTK_WINDOW (window));
3900 gtk_widget_grab_focus (window->priv->view);
3902 if (window->priv->metadata && !ev_window_is_empty (window))
3903 ev_metadata_set_boolean (window->priv->metadata, "fullscreen", TRUE);
3907 ev_window_stop_fullscreen (EvWindow *window,
3908 gboolean unfullscreen_window)
3910 if (!ev_document_model_get_fullscreen (window->priv->model))
3913 g_object_set (G_OBJECT (window->priv->scrolled_window),
3914 "shadow-type", GTK_SHADOW_IN,
3917 ev_document_model_set_fullscreen (window->priv->model, FALSE);
3918 ev_window_update_fullscreen_action (window);
3919 update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR, FALSE);
3920 update_chrome_visibility (window);
3921 if (unfullscreen_window)
3922 gtk_window_unfullscreen (GTK_WINDOW (window));
3924 if (window->priv->metadata && !ev_window_is_empty (window))
3925 ev_metadata_set_boolean (window->priv->metadata, "fullscreen", FALSE);
3929 ev_window_cmd_view_fullscreen (GtkAction *action, EvWindow *window)
3931 gboolean fullscreen;
3933 fullscreen = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
3935 ev_window_run_fullscreen (window);
3937 ev_window_stop_fullscreen (window, TRUE);
3942 ev_window_update_presentation_action (EvWindow *window)
3946 action = gtk_action_group_get_action (window->priv->action_group, "ViewPresentation");
3947 g_signal_handlers_block_by_func
3948 (action, G_CALLBACK (ev_window_cmd_view_presentation), window);
3949 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
3950 EV_WINDOW_IS_PRESENTATION (window));
3951 g_signal_handlers_unblock_by_func
3952 (action, G_CALLBACK (ev_window_cmd_view_presentation), window);
3956 ev_window_view_presentation_finished (EvWindow *window)
3958 ev_window_stop_presentation (window, TRUE);
3962 ev_window_run_presentation (EvWindow *window)
3964 gboolean fullscreen_window = TRUE;
3967 gboolean inverted_colors;
3969 if (EV_WINDOW_IS_PRESENTATION (window))
3972 if (ev_document_model_get_fullscreen (window->priv->model)) {
3973 ev_window_stop_fullscreen (window, FALSE);
3974 fullscreen_window = FALSE;
3977 current_page = ev_document_model_get_page (window->priv->model);
3978 rotation = ev_document_model_get_rotation (window->priv->model);
3979 inverted_colors = ev_document_model_get_inverted_colors (window->priv->model);
3980 window->priv->presentation_view = ev_view_presentation_new (window->priv->document,
3984 g_signal_connect_swapped (window->priv->presentation_view, "finished",
3985 G_CALLBACK (ev_window_view_presentation_finished),
3988 gtk_box_pack_start (GTK_BOX (window->priv->main_box),
3989 window->priv->presentation_view,
3992 gtk_widget_hide (window->priv->hpaned);
3993 ev_window_update_presentation_action (window);
3994 update_chrome_visibility (window);
3996 gtk_widget_grab_focus (window->priv->presentation_view);
3997 if (fullscreen_window)
3998 gtk_window_fullscreen (GTK_WINDOW (window));
4000 gtk_widget_show (window->priv->presentation_view);
4002 ev_application_screensaver_disable (EV_APP);
4004 if (window->priv->metadata && !ev_window_is_empty (window))
4005 ev_metadata_set_boolean (window->priv->metadata, "presentation", TRUE);
4009 ev_window_stop_presentation (EvWindow *window,
4010 gboolean unfullscreen_window)
4014 if (!EV_WINDOW_IS_PRESENTATION (window))
4017 current_page = ev_view_presentation_get_current_page (EV_VIEW_PRESENTATION (window->priv->presentation_view));
4018 ev_document_model_set_page (window->priv->model, current_page);
4020 gtk_container_remove (GTK_CONTAINER (window->priv->main_box),
4021 window->priv->presentation_view);
4022 window->priv->presentation_view = NULL;
4024 gtk_widget_show (window->priv->hpaned);
4025 ev_window_update_presentation_action (window);
4026 update_chrome_visibility (window);
4027 if (unfullscreen_window)
4028 gtk_window_unfullscreen (GTK_WINDOW (window));
4030 gtk_widget_grab_focus (window->priv->view);
4032 ev_application_screensaver_enable (EV_APP);
4034 if (window->priv->metadata && !ev_window_is_empty (window))
4035 ev_metadata_set_boolean (window->priv->metadata, "presentation", FALSE);
4039 ev_window_cmd_view_presentation (GtkAction *action, EvWindow *window)
4041 gboolean presentation;
4043 presentation = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
4045 ev_window_run_presentation (window);
4050 ev_window_setup_gtk_settings (EvWindow *window)
4052 GtkSettings *settings;
4054 gchar *menubar_accel_accel;
4056 screen = gtk_window_get_screen (GTK_WINDOW (window));
4057 settings = gtk_settings_get_for_screen (screen);
4059 g_object_get (settings,
4060 "gtk-menu-bar-accel", &menubar_accel_accel,
4062 if (menubar_accel_accel != NULL && menubar_accel_accel[0] != '\0') {
4063 gtk_accelerator_parse (menubar_accel_accel,
4064 &window->priv->menubar_accel_keyval,
4065 &window->priv->menubar_accel_modifier);
4066 if (window->priv->menubar_accel_keyval == 0) {
4067 g_warning ("Failed to parse menu bar accelerator '%s'\n",
4068 menubar_accel_accel);
4071 window->priv->menubar_accel_keyval = 0;
4072 window->priv->menubar_accel_modifier = 0;
4075 g_free (menubar_accel_accel);
4079 ev_window_update_max_min_scale (EvWindow *window)
4083 gdouble min_width, min_height;
4084 gdouble width, height;
4086 gint rotation = ev_document_model_get_rotation (window->priv->model);
4088 if (!window->priv->document)
4091 dpi = get_screen_dpi (window) / 72.0;
4093 ev_document_get_min_page_size (window->priv->document, &min_width, &min_height);
4094 width = (rotation == 0 || rotation == 180) ? min_width : min_height;
4095 height = (rotation == 0 || rotation == 180) ? min_height : min_width;
4096 max_scale = sqrt (PAGE_CACHE_SIZE / (width * dpi * 4 * height * dpi));
4098 action = gtk_action_group_get_action (window->priv->action_group,
4099 ZOOM_CONTROL_ACTION);
4100 ephy_zoom_action_set_max_zoom_level (EPHY_ZOOM_ACTION (action), max_scale * dpi);
4102 ev_document_model_set_min_scale (window->priv->model, MIN_SCALE * dpi);
4103 ev_document_model_set_max_scale (window->priv->model, max_scale * dpi);
4107 ev_window_screen_changed (GtkWidget *widget,
4108 GdkScreen *old_screen)
4110 EvWindow *window = EV_WINDOW (widget);
4113 screen = gtk_widget_get_screen (widget);
4114 if (screen == old_screen)
4117 ev_window_setup_gtk_settings (window);
4118 ev_window_update_max_min_scale (window);
4120 if (GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed) {
4121 GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed (widget, old_screen);
4126 ev_window_state_event (GtkWidget *widget,
4127 GdkEventWindowState *event)
4129 EvWindow *window = EV_WINDOW (widget);
4131 if (GTK_WIDGET_CLASS (ev_window_parent_class)->window_state_event) {
4132 GTK_WIDGET_CLASS (ev_window_parent_class)->window_state_event (widget, event);
4135 if ((event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) == 0)
4138 if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) {
4139 if (ev_document_model_get_fullscreen (window->priv->model) || EV_WINDOW_IS_PRESENTATION (window))
4142 ev_window_run_fullscreen (window);
4144 if (ev_document_model_get_fullscreen (window->priv->model))
4145 ev_window_stop_fullscreen (window, FALSE);
4146 else if (EV_WINDOW_IS_PRESENTATION (window))
4147 ev_window_stop_presentation (window, FALSE);
4154 ev_window_set_page_mode (EvWindow *window,
4155 EvWindowPageMode page_mode)
4157 GtkWidget *child = NULL;
4158 GtkWidget *real_child;
4160 if (window->priv->page_mode == page_mode)
4163 window->priv->page_mode = page_mode;
4165 switch (page_mode) {
4166 case PAGE_MODE_DOCUMENT:
4167 child = window->priv->view;
4169 case PAGE_MODE_PASSWORD:
4170 child = window->priv->password_view;
4173 g_assert_not_reached ();
4176 real_child = gtk_bin_get_child (GTK_BIN (window->priv->scrolled_window));
4177 if (child != real_child) {
4178 gtk_container_remove (GTK_CONTAINER (window->priv->scrolled_window),
4180 gtk_container_add (GTK_CONTAINER (window->priv->scrolled_window),
4183 ev_window_update_actions (window);
4188 ev_window_cmd_edit_rotate_left (GtkAction *action, EvWindow *ev_window)
4190 gint rotation = ev_document_model_get_rotation (ev_window->priv->model);
4192 ev_document_model_set_rotation (ev_window->priv->model, rotation - 90);
4196 ev_window_cmd_edit_rotate_right (GtkAction *action, EvWindow *ev_window)
4198 gint rotation = ev_document_model_get_rotation (ev_window->priv->model);
4200 ev_document_model_set_rotation (ev_window->priv->model, rotation + 90);
4204 ev_window_cmd_view_inverted_colors (GtkAction *action, EvWindow *ev_window)
4206 gboolean inverted_colors = ev_document_model_get_inverted_colors (ev_window->priv->model);
4208 ev_document_model_set_inverted_colors (ev_window->priv->model, !inverted_colors);
4212 ev_window_cmd_edit_toolbar_cb (GtkDialog *dialog,
4214 EvWindow *ev_window)
4216 EggEditableToolbar *toolbar;
4217 gchar *toolbars_file;
4219 toolbar = EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar);
4220 egg_editable_toolbar_set_edit_mode (toolbar, FALSE);
4222 toolbars_file = g_build_filename (ev_application_get_dot_dir (EV_APP, TRUE),
4223 "evince_toolbar.xml", NULL);
4224 egg_toolbars_model_save_toolbars (egg_editable_toolbar_get_model (toolbar),
4225 toolbars_file, "1.0");
4226 g_free (toolbars_file);
4228 gtk_widget_destroy (GTK_WIDGET (dialog));
4232 ev_window_cmd_edit_toolbar (GtkAction *action, EvWindow *ev_window)
4236 GtkWidget *content_area;
4237 EggEditableToolbar *toolbar;
4239 dialog = gtk_dialog_new_with_buttons (_("Toolbar Editor"),
4240 GTK_WINDOW (ev_window),
4241 GTK_DIALOG_DESTROY_WITH_PARENT,
4245 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
4246 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
4247 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)), 5);
4248 gtk_box_set_spacing (GTK_BOX (content_area), 2);
4249 gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400);
4251 toolbar = EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar);
4252 editor = egg_toolbar_editor_new (ev_window->priv->ui_manager,
4253 egg_editable_toolbar_get_model (toolbar));
4255 gtk_container_set_border_width (GTK_CONTAINER (editor), 5);
4256 gtk_box_set_spacing (GTK_BOX (EGG_TOOLBAR_EDITOR (editor)), 5);
4258 gtk_container_add (GTK_CONTAINER (content_area), editor);
4260 egg_editable_toolbar_set_edit_mode (toolbar, TRUE);
4262 g_signal_connect (dialog, "response",
4263 G_CALLBACK (ev_window_cmd_edit_toolbar_cb),
4265 gtk_widget_show_all (dialog);
4269 ev_window_cmd_edit_save_settings (GtkAction *action, EvWindow *ev_window)
4271 EvWindowPrivate *priv = ev_window->priv;
4272 EvDocumentModel *model = priv->model;
4273 GSettings *settings = priv->default_settings;
4275 g_settings_set_boolean (settings, "continuous",
4276 ev_document_model_get_continuous (model));
4277 g_settings_set_boolean (settings, "dual-page",
4278 ev_document_model_get_dual_page (model));
4279 g_settings_set_boolean (settings, "fullscreen",
4280 ev_document_model_get_fullscreen (model));
4281 g_settings_set_boolean (settings, "inverted-colors",
4282 ev_document_model_get_inverted_colors (model));
4283 g_settings_set_enum (settings, "sizing-mode",
4284 ev_document_model_get_sizing_mode (model));
4285 g_settings_set_boolean (settings, "show-toolbar",
4286 gtk_widget_get_visible (priv->toolbar));
4287 g_settings_set_boolean (settings, "show-sidebar",
4288 gtk_widget_get_visible (priv->sidebar));
4289 g_settings_set_int (settings, "sidebar-size",
4290 gtk_paned_get_position (GTK_PANED (priv->hpaned)));
4291 g_settings_set_string (settings, "sidebar-page",
4292 ev_window_sidebar_get_current_page_id (ev_window));
4293 g_settings_apply (settings);
4297 ev_window_cmd_view_zoom_in (GtkAction *action, EvWindow *ev_window)
4299 g_return_if_fail (EV_IS_WINDOW (ev_window));
4301 ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE);
4302 ev_view_zoom_in (EV_VIEW (ev_window->priv->view));
4306 ev_window_cmd_view_zoom_out (GtkAction *action, EvWindow *ev_window)
4308 g_return_if_fail (EV_IS_WINDOW (ev_window));
4310 ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE);
4311 ev_view_zoom_out (EV_VIEW (ev_window->priv->view));
4315 ev_window_cmd_go_previous_page (GtkAction *action, EvWindow *ev_window)
4317 g_return_if_fail (EV_IS_WINDOW (ev_window));
4319 ev_view_previous_page (EV_VIEW (ev_window->priv->view));
4323 ev_window_cmd_go_next_page (GtkAction *action, EvWindow *ev_window)
4325 g_return_if_fail (EV_IS_WINDOW (ev_window));
4327 ev_view_next_page (EV_VIEW (ev_window->priv->view));
4331 ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window)
4333 g_return_if_fail (EV_IS_WINDOW (ev_window));
4335 ev_document_model_set_page (ev_window->priv->model, 0);
4339 ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window)
4341 g_return_if_fail (EV_IS_WINDOW (ev_window));
4343 ev_document_model_set_page (ev_window->priv->model,
4344 ev_document_get_n_pages (ev_window->priv->document) - 1);
4348 ev_window_cmd_go_forward (GtkAction *action, EvWindow *ev_window)
4350 int n_pages, current_page;
4352 g_return_if_fail (EV_IS_WINDOW (ev_window));
4354 n_pages = ev_document_get_n_pages (ev_window->priv->document);
4355 current_page = ev_document_model_get_page (ev_window->priv->model);
4357 if (current_page + 10 < n_pages) {
4358 ev_document_model_set_page (ev_window->priv->model, current_page + 10);
4363 ev_window_cmd_go_backward (GtkAction *action, EvWindow *ev_window)
4367 g_return_if_fail (EV_IS_WINDOW (ev_window));
4369 current_page = ev_document_model_get_page (ev_window->priv->model);
4371 if (current_page - 10 >= 0) {
4372 ev_document_model_set_page (ev_window->priv->model, current_page - 10);
4377 ev_window_cmd_bookmark_activate (GtkAction *action,
4380 guint page = ev_bookmark_action_get_page (EV_BOOKMARK_ACTION (action));
4382 ev_document_model_set_page (window->priv->model, page);
4386 compare_bookmarks (EvBookmark *a,
4389 return strcmp (a->title, b->title);
4393 ev_window_setup_bookmarks (EvWindow *window)
4397 if (!window->priv->bookmarks)
4400 if (window->priv->bookmarks_ui_id > 0) {
4401 gtk_ui_manager_remove_ui (window->priv->ui_manager,
4402 window->priv->bookmarks_ui_id);
4403 gtk_ui_manager_ensure_update (window->priv->ui_manager);
4405 window->priv->bookmarks_ui_id = gtk_ui_manager_new_merge_id (window->priv->ui_manager);
4407 if (window->priv->bookmarks_action_group) {
4408 gtk_ui_manager_remove_action_group (window->priv->ui_manager,
4409 window->priv->bookmarks_action_group);
4410 g_object_unref (window->priv->bookmarks_action_group);
4412 window->priv->bookmarks_action_group = gtk_action_group_new ("BookmarksActions");
4413 gtk_ui_manager_insert_action_group (window->priv->ui_manager,
4414 window->priv->bookmarks_action_group, -1);
4416 items = ev_bookmarks_get_bookmarks (window->priv->bookmarks);
4417 items = g_list_sort (items, (GCompareFunc)compare_bookmarks);
4419 for (l = items; l && l->data; l = g_list_next (l)) {
4420 EvBookmark *bm = (EvBookmark *)l->data;
4423 action = ev_bookmark_action_new (bm);
4424 g_signal_connect (action, "activate",
4425 G_CALLBACK (ev_window_cmd_bookmark_activate),
4427 gtk_action_group_add_action (window->priv->bookmarks_action_group,
4430 gtk_ui_manager_add_ui (window->priv->ui_manager,
4431 window->priv->bookmarks_ui_id,
4432 "/MainMenu/BookmarksMenu/BookmarksItems",
4433 gtk_action_get_label (action),
4434 gtk_action_get_name (action),
4435 GTK_UI_MANAGER_MENUITEM,
4438 g_object_unref (action);
4441 g_list_free (items);
4445 ev_window_cmd_bookmarks_add (GtkAction *action,
4452 bm.page = ev_document_model_get_page (window->priv->model);
4453 page_label = ev_document_get_page_label (window->priv->document, bm.page);
4454 page_title = ev_window_get_page_title (window, page_label);
4455 bm.title = page_title ? page_title : g_strdup_printf (_("Page %s"), page_label);
4456 g_free (page_label);
4458 /* EvBookmarks takes ownership of bookmark */
4459 ev_bookmarks_add (window->priv->bookmarks, &bm);
4463 ev_window_cmd_view_reload (GtkAction *action, EvWindow *ev_window)
4465 ev_window_reload_document (ev_window, NULL);
4469 ev_window_cmd_view_autoscroll (GtkAction *action, EvWindow *ev_window)
4471 ev_view_autoscroll_start (EV_VIEW (ev_window->priv->view));
4474 #if OFFLINE_HELP_ENABLED
4475 #define EV_HELP "ghelp:evince"
4477 #define EV_HELP "http://library.gnome.org/users/evince/stable/"
4481 ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window)
4483 GError *error = NULL;
4485 gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (ev_window)),
4487 gtk_get_current_event_time (),
4490 ev_window_error_message (ev_window, error,
4491 "%s", _("There was an error displaying help"));
4492 g_error_free (error);
4497 ev_window_cmd_leave_fullscreen (GtkAction *action, EvWindow *window)
4499 ev_window_stop_fullscreen (window, TRUE);
4503 ev_window_cmd_start_presentation (GtkAction *action, EvWindow *window)
4505 ev_window_run_presentation (window);
4509 ev_window_cmd_escape (GtkAction *action, EvWindow *window)
4513 ev_view_autoscroll_stop (EV_VIEW (window->priv->view));
4515 widget = gtk_window_get_focus (GTK_WINDOW (window));
4516 if (widget && gtk_widget_get_ancestor (widget, EGG_TYPE_FIND_BAR)) {
4517 update_chrome_flag (window, EV_CHROME_FINDBAR, FALSE);
4518 update_chrome_visibility (window);
4519 gtk_widget_grab_focus (window->priv->view);
4521 gboolean fullscreen;
4523 fullscreen = ev_document_model_get_fullscreen (window->priv->model);
4526 ev_window_stop_fullscreen (window, TRUE);
4527 } else if (EV_WINDOW_IS_PRESENTATION (window)) {
4528 ev_window_stop_presentation (window, TRUE);
4529 gtk_widget_grab_focus (window->priv->view);
4531 gtk_widget_grab_focus (window->priv->view);
4534 if (fullscreen && EV_WINDOW_IS_PRESENTATION (window))
4535 g_warning ("Both fullscreen and presentation set somehow");
4540 save_sizing_mode (EvWindow *window)
4543 GEnumValue *enum_value;
4545 if (!window->priv->metadata || ev_window_is_empty (window))
4548 mode = ev_document_model_get_sizing_mode (window->priv->model);
4549 enum_value = g_enum_get_value (g_type_class_peek (EV_TYPE_SIZING_MODE), mode);
4550 ev_metadata_set_string (window->priv->metadata, "sizing_mode",
4551 enum_value->value_nick);
4555 ev_window_document_changed_cb (EvDocumentModel *model,
4557 EvWindow *ev_window)
4559 ev_window_set_document (ev_window,
4560 ev_document_model_get_document (model));
4564 ev_window_sizing_mode_changed_cb (EvDocumentModel *model,
4566 EvWindow *ev_window)
4568 EvSizingMode sizing_mode = ev_document_model_get_sizing_mode (model);
4570 g_object_set (ev_window->priv->scrolled_window,
4571 "hscrollbar-policy",
4572 sizing_mode == EV_SIZING_FREE ?
4573 GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER,
4574 "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
4577 update_sizing_buttons (ev_window);
4578 save_sizing_mode (ev_window);
4582 ev_window_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *ev_window)
4584 ev_window_update_actions (ev_window);
4586 if (!ev_window->priv->metadata)
4589 if (ev_document_model_get_sizing_mode (model) == EV_SIZING_FREE && !ev_window_is_empty (ev_window)) {
4592 zoom = ev_document_model_get_scale (model);
4593 zoom *= 72.0 / get_screen_dpi (ev_window);
4594 ev_metadata_set_double (ev_window->priv->metadata, "zoom", zoom);
4599 ev_window_update_continuous_action (EvWindow *window)
4603 action = gtk_action_group_get_action (window->priv->action_group, "ViewContinuous");
4604 g_signal_handlers_block_by_func
4605 (action, G_CALLBACK (ev_window_cmd_continuous), window);
4606 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
4607 ev_document_model_get_continuous (window->priv->model));
4608 g_signal_handlers_unblock_by_func
4609 (action, G_CALLBACK (ev_window_cmd_continuous), window);
4613 ev_window_update_dual_page_action (EvWindow *window)
4617 action = gtk_action_group_get_action (window->priv->action_group, "ViewDual");
4618 g_signal_handlers_block_by_func
4619 (action, G_CALLBACK (ev_window_cmd_dual), window);
4620 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
4621 ev_document_model_get_dual_page (window->priv->model));
4622 g_signal_handlers_unblock_by_func
4623 (action, G_CALLBACK (ev_window_cmd_dual), window);
4627 ev_window_continuous_changed_cb (EvDocumentModel *model,
4629 EvWindow *ev_window)
4631 ev_window_update_continuous_action (ev_window);
4633 if (ev_window->priv->metadata && !ev_window_is_empty (ev_window))
4634 ev_metadata_set_boolean (ev_window->priv->metadata, "continuous",
4635 ev_document_model_get_continuous (model));
4639 ev_window_rotation_changed_cb (EvDocumentModel *model,
4643 gint rotation = ev_document_model_get_rotation (model);
4645 if (window->priv->metadata && !ev_window_is_empty (window))
4646 ev_metadata_set_int (window->priv->metadata, "rotation",
4649 ev_window_update_max_min_scale (window);
4650 ev_window_refresh_window_thumbnail (window);
4654 ev_window_update_inverted_colors_action (EvWindow *window)
4658 action = gtk_action_group_get_action (window->priv->action_group, "ViewInvertedColors");
4659 g_signal_handlers_block_by_func
4660 (action, G_CALLBACK (ev_window_cmd_view_inverted_colors), window);
4661 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
4662 ev_document_model_get_inverted_colors (window->priv->model));
4663 g_signal_handlers_unblock_by_func
4664 (action, G_CALLBACK (ev_window_cmd_view_inverted_colors), window);
4668 ev_window_inverted_colors_changed_cb (EvDocumentModel *model,
4672 gboolean inverted_colors = ev_document_model_get_inverted_colors (model);
4674 ev_window_update_inverted_colors_action (window);
4676 if (window->priv->metadata && !ev_window_is_empty (window))
4677 ev_metadata_set_boolean (window->priv->metadata, "inverted-colors",
4680 ev_window_refresh_window_thumbnail (window);
4684 ev_window_dual_mode_changed_cb (EvDocumentModel *model,
4686 EvWindow *ev_window)
4688 ev_window_update_dual_page_action (ev_window);
4690 if (ev_window->priv->metadata && !ev_window_is_empty (ev_window))
4691 ev_metadata_set_boolean (ev_window->priv->metadata, "dual-page",
4692 ev_document_model_get_dual_page (model));
4696 build_comments_string (EvDocument *document)
4698 gchar *comments = NULL;
4699 EvDocumentBackendInfo info;
4701 if (document && ev_document_get_backend_info (document, &info)) {
4702 comments = g_strdup_printf (
4703 _("Document Viewer\nUsing %s (%s)"),
4704 info.name, info.version);
4706 comments = g_strdup_printf (
4707 _("Document Viewer"));
4714 ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window)
4716 const char *authors[] = {
4717 "Martin Kretzschmar <m_kretzschmar@gmx.net>",
4718 "Jonathan Blandford <jrb@gnome.org>",
4719 "Marco Pesenti Gritti <marco@gnome.org>",
4720 "Nickolay V. Shmyrev <nshmyrev@yandex.ru>",
4721 "Bryan Clark <clarkbw@gnome.org>",
4722 "Carlos Garcia Campos <carlosgc@gnome.org>",
4723 "Wouter Bolsterlee <wbolster@gnome.org>",
4724 "Christian Persch <chpe" "\100" "gnome.org>",
4728 const char *documenters[] = {
4729 "Nickolay V. Shmyrev <nshmyrev@yandex.ru>",
4733 const char *license[] = {
4734 N_("Evince is free software; you can redistribute it and/or modify "
4735 "it under the terms of the GNU General Public License as published by "
4736 "the Free Software Foundation; either version 2 of the License, or "
4737 "(at your option) any later version.\n"),
4738 N_("Evince is distributed in the hope that it will be useful, "
4739 "but WITHOUT ANY WARRANTY; without even the implied warranty of "
4740 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
4741 "GNU General Public License for more details.\n"),
4742 N_("You should have received a copy of the GNU General Public License "
4743 "along with Evince; if not, write to the Free Software Foundation, Inc., "
4744 "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n")
4747 char *license_trans;
4753 for (p = authors; *p; ++p)
4756 for (p = documenters; *p; ++p)
4760 license_trans = g_strconcat (_(license[0]), "\n", _(license[1]), "\n",
4761 _(license[2]), "\n", NULL);
4763 comments = build_comments_string (ev_window->priv->document);
4765 gtk_show_about_dialog (
4766 GTK_WINDOW (ev_window),
4767 "name", _("Evince"),
4770 _("© 1996–2010 The Evince authors"),
4771 "license", license_trans,
4772 "website", "http://www.gnome.org/projects/evince",
4773 "comments", comments,
4775 "documenters", documenters,
4776 "translator-credits", _("translator-credits"),
4777 "logo-icon-name", "evince",
4778 "wrap-license", TRUE,
4782 g_free (license_trans);
4786 ev_window_view_toolbar_cb (GtkAction *action, EvWindow *ev_window)
4790 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
4791 update_chrome_flag (ev_window, EV_CHROME_TOOLBAR, active);
4792 update_chrome_visibility (ev_window);
4793 if (ev_window->priv->metadata)
4794 ev_metadata_set_boolean (ev_window->priv->metadata, "show_toolbar", active);
4798 ev_window_view_sidebar_cb (GtkAction *action, EvWindow *ev_window)
4800 if (EV_WINDOW_IS_PRESENTATION (ev_window))
4803 update_chrome_flag (ev_window, EV_CHROME_SIDEBAR,
4804 gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
4805 update_chrome_visibility (ev_window);
4809 ev_window_sidebar_current_page_changed_cb (EvSidebar *ev_sidebar,
4811 EvWindow *ev_window)
4813 if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) {
4814 ev_metadata_set_string (ev_window->priv->metadata,
4816 ev_window_sidebar_get_current_page_id (ev_window));
4821 ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar,
4823 EvWindow *ev_window)
4827 action = gtk_action_group_get_action (ev_window->priv->action_group, "ViewSidebar");
4829 if (!EV_WINDOW_IS_PRESENTATION (ev_window)) {
4830 gboolean visible = gtk_widget_get_visible (GTK_WIDGET (ev_sidebar));
4832 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), visible);
4834 if (ev_window->priv->metadata)
4835 ev_metadata_set_boolean (ev_window->priv->metadata, "sidebar_visibility",
4841 view_menu_link_popup (EvWindow *ev_window,
4844 gboolean show_external = FALSE;
4845 gboolean show_internal = FALSE;
4848 if (ev_window->priv->link)
4849 g_object_unref (ev_window->priv->link);
4852 ev_window->priv->link = g_object_ref (link);
4854 ev_window->priv->link = NULL;
4856 if (ev_window->priv->link) {
4857 EvLinkAction *ev_action;
4859 ev_action = ev_link_get_action (link);
4861 switch (ev_link_action_get_action_type (ev_action)) {
4862 case EV_LINK_ACTION_TYPE_GOTO_DEST:
4863 case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
4864 show_internal = TRUE;
4866 case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
4867 case EV_LINK_ACTION_TYPE_LAUNCH:
4868 show_external = TRUE;
4876 action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
4878 gtk_action_set_visible (action, show_external);
4880 action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
4882 gtk_action_set_visible (action, show_external);
4884 action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
4886 gtk_action_set_visible (action, show_internal);
4888 action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
4889 "OpenLinkNewWindow");
4890 gtk_action_set_visible (action, show_internal);
4894 view_menu_image_popup (EvWindow *ev_window,
4898 gboolean show_image = FALSE;
4900 if (ev_window->priv->image)
4901 g_object_unref (ev_window->priv->image);
4904 ev_window->priv->image = g_object_ref (image);
4906 ev_window->priv->image = NULL;
4908 show_image = (ev_window->priv->image != NULL);
4910 action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
4912 gtk_action_set_visible (action, show_image);
4914 action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
4916 gtk_action_set_visible (action, show_image);
4920 view_menu_annot_popup (EvWindow *ev_window,
4921 EvAnnotation *annot)
4924 gboolean show_annot = FALSE;
4926 if (ev_window->priv->annot)
4927 g_object_unref (ev_window->priv->annot);
4928 ev_window->priv->annot = (annot) ? g_object_ref (annot) : NULL;
4930 action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
4932 gtk_action_set_visible (action, (annot != NULL && EV_IS_ANNOTATION_MARKUP (annot)));
4934 if (annot && EV_IS_ANNOTATION_ATTACHMENT (annot)) {
4935 EvAttachment *attachment;
4937 attachment = ev_annotation_attachment_get_attachment (EV_ANNOTATION_ATTACHMENT (annot));
4940 if (ev_window->priv->attach_list) {
4941 g_list_foreach (ev_window->priv->attach_list,
4942 (GFunc) g_object_unref, NULL);
4943 g_list_free (ev_window->priv->attach_list);
4944 ev_window->priv->attach_list = NULL;
4946 ev_window->priv->attach_list =
4947 g_list_prepend (ev_window->priv->attach_list,
4948 g_object_ref (attachment));
4952 action = gtk_action_group_get_action (ev_window->priv->attachment_popup_action_group,
4954 gtk_action_set_visible (action, show_annot);
4956 action = gtk_action_group_get_action (ev_window->priv->attachment_popup_action_group,
4957 "SaveAttachmentAs");
4958 gtk_action_set_visible (action, show_annot);
4962 view_menu_popup_cb (EvView *view,
4964 EvWindow *ev_window)
4967 gboolean has_link = FALSE;
4968 gboolean has_image = FALSE;
4969 gboolean has_annot = FALSE;
4971 for (l = items; l; l = g_list_next (l)) {
4972 if (EV_IS_LINK (l->data)) {
4973 view_menu_link_popup (ev_window, EV_LINK (l->data));
4975 } else if (EV_IS_IMAGE (l->data)) {
4976 view_menu_image_popup (ev_window, EV_IMAGE (l->data));
4978 } else if (EV_IS_ANNOTATION (l->data)) {
4979 view_menu_annot_popup (ev_window, EV_ANNOTATION (l->data));
4985 view_menu_link_popup (ev_window, NULL);
4987 view_menu_image_popup (ev_window, NULL);
4989 view_menu_annot_popup (ev_window, NULL);
4991 gtk_menu_popup (GTK_MENU (ev_window->priv->view_popup),
4992 NULL, NULL, NULL, NULL,
4993 3, gtk_get_current_event_time ());
4998 attachment_bar_menu_popup_cb (EvSidebarAttachments *attachbar,
5000 EvWindow *ev_window)
5004 g_assert (attach_list != NULL);
5006 if (ev_window->priv->attach_list) {
5007 g_list_foreach (ev_window->priv->attach_list,
5008 (GFunc) g_object_unref, NULL);
5009 g_list_free (ev_window->priv->attach_list);
5012 ev_window->priv->attach_list = attach_list;
5014 popup = ev_window->priv->attachment_popup;
5016 gtk_menu_popup (GTK_MENU (popup), NULL, NULL,
5018 3, gtk_get_current_event_time ());
5024 ev_window_update_find_status_message (EvWindow *ev_window)
5028 if (!ev_window->priv->find_job)
5031 if (ev_job_is_finished (ev_window->priv->find_job)) {
5032 EvJobFind *job_find = EV_JOB_FIND (ev_window->priv->find_job);
5034 if (ev_job_find_has_results (job_find)) {
5037 n_results = ev_job_find_get_n_results (job_find,
5038 ev_document_model_get_page (ev_window->priv->model));
5039 /* TRANS: Sometimes this could be better translated as
5040 "%d hit(s) on this page". Therefore this string
5041 contains plural cases. */
5042 message = g_strdup_printf (ngettext ("%d found on this page",
5043 "%d found on this page",
5047 message = g_strdup (_("Not found"));
5052 percent = ev_job_find_get_progress (EV_JOB_FIND (ev_window->priv->find_job));
5053 message = g_strdup_printf (_("%3d%% remaining to search"),
5054 (gint) ((1.0 - percent) * 100));
5057 egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar), message);
5062 ev_window_find_job_finished_cb (EvJobFind *job,
5063 EvWindow *ev_window)
5065 ev_window_update_find_status_message (ev_window);
5069 ev_window_find_job_updated_cb (EvJobFind *job,
5071 EvWindow *ev_window)
5073 ev_window_update_actions (ev_window);
5075 ev_view_find_changed (EV_VIEW (ev_window->priv->view),
5076 ev_job_find_get_results (job),
5078 ev_window_update_find_status_message (ev_window);
5082 ev_window_clear_find_job (EvWindow *ev_window)
5084 if (ev_window->priv->find_job != NULL) {
5085 if (!ev_job_is_finished (ev_window->priv->find_job))
5086 ev_job_cancel (ev_window->priv->find_job);
5088 g_signal_handlers_disconnect_by_func (ev_window->priv->find_job,
5089 ev_window_find_job_finished_cb,
5091 g_signal_handlers_disconnect_by_func (ev_window->priv->find_job,
5092 ev_window_find_job_updated_cb,
5094 g_object_unref (ev_window->priv->find_job);
5095 ev_window->priv->find_job = NULL;
5100 find_bar_previous_cb (EggFindBar *find_bar,
5101 EvWindow *ev_window)
5103 ev_view_find_previous (EV_VIEW (ev_window->priv->view));
5107 find_bar_next_cb (EggFindBar *find_bar,
5108 EvWindow *ev_window)
5110 ev_view_find_next (EV_VIEW (ev_window->priv->view));
5114 find_bar_close_cb (EggFindBar *find_bar,
5115 EvWindow *ev_window)
5117 ev_view_find_cancel (EV_VIEW (ev_window->priv->view));
5118 ev_window_clear_find_job (ev_window);
5119 update_chrome_flag (ev_window, EV_CHROME_FINDBAR, FALSE);
5120 update_chrome_visibility (ev_window);
5124 find_bar_search_changed_cb (EggFindBar *find_bar,
5126 EvWindow *ev_window)
5128 gboolean case_sensitive;
5129 const char *search_string;
5131 if (!ev_window->priv->document || !EV_IS_DOCUMENT_FIND (ev_window->priv->document))
5134 /* Either the string or case sensitivity could have changed. */
5135 case_sensitive = egg_find_bar_get_case_sensitive (find_bar);
5136 search_string = egg_find_bar_get_search_string (find_bar);
5138 ev_view_find_search_changed (EV_VIEW (ev_window->priv->view));
5140 ev_window_clear_find_job (ev_window);
5142 if (search_string && search_string[0]) {
5143 ev_window->priv->find_job = ev_job_find_new (ev_window->priv->document,
5144 ev_document_model_get_page (ev_window->priv->model),
5145 ev_document_get_n_pages (ev_window->priv->document),
5148 g_signal_connect (ev_window->priv->find_job, "finished",
5149 G_CALLBACK (ev_window_find_job_finished_cb),
5151 g_signal_connect (ev_window->priv->find_job, "updated",
5152 G_CALLBACK (ev_window_find_job_updated_cb),
5154 ev_job_scheduler_push_job (ev_window->priv->find_job, EV_JOB_PRIORITY_NONE);
5156 ev_window_update_actions (ev_window);
5157 egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar),
5159 gtk_widget_queue_draw (GTK_WIDGET (ev_window->priv->view));
5164 find_bar_visibility_changed_cb (EggFindBar *find_bar,
5166 EvWindow *ev_window)
5170 visible = gtk_widget_get_visible (GTK_WIDGET (find_bar));
5172 if (ev_window->priv->document &&
5173 EV_IS_DOCUMENT_FIND (ev_window->priv->document)) {
5174 ev_view_find_set_highlight_search (EV_VIEW (ev_window->priv->view), visible);
5175 ev_view_find_search_changed (EV_VIEW (ev_window->priv->view));
5176 ev_window_update_actions (ev_window);
5179 find_bar_search_changed_cb (find_bar, NULL, ev_window);
5181 egg_find_bar_set_status_text (EGG_FIND_BAR (ev_window->priv->find_bar), NULL);
5186 find_bar_scroll (EggFindBar *find_bar,
5187 GtkScrollType scroll,
5188 EvWindow *ev_window)
5190 ev_view_scroll (EV_VIEW (ev_window->priv->view), scroll, FALSE);
5194 zoom_control_changed_cb (EphyZoomAction *action,
5196 EvWindow *ev_window)
5200 if (zoom == EPHY_ZOOM_BEST_FIT) {
5201 mode = EV_SIZING_BEST_FIT;
5202 } else if (zoom == EPHY_ZOOM_FIT_WIDTH) {
5203 mode = EV_SIZING_FIT_WIDTH;
5205 mode = EV_SIZING_FREE;
5208 ev_document_model_set_sizing_mode (ev_window->priv->model, mode);
5210 if (mode == EV_SIZING_FREE) {
5211 ev_document_model_set_scale (ev_window->priv->model,
5212 zoom * get_screen_dpi (ev_window) / 72.0);
5217 ev_window_drag_data_received (GtkWidget *widget,
5218 GdkDragContext *context,
5221 GtkSelectionData *selection_data,
5226 EvWindow *window = EV_WINDOW (widget);
5229 GSList *uri_list = NULL;
5232 source = gtk_drag_get_source_widget (context);
5233 if (source && widget == gtk_widget_get_toplevel (source)) {
5234 gtk_drag_finish (context, FALSE, FALSE, time);
5238 uris = gtk_selection_data_get_uris (selection_data);
5240 gtk_drag_finish (context, FALSE, FALSE, time);
5244 for (i = 0; uris[i]; i++) {
5245 uri_list = g_slist_prepend (uri_list, (gpointer) uris[i]);
5248 ev_application_open_uri_list (EV_APP, uri_list,
5249 gtk_window_get_screen (GTK_WINDOW (window)),
5251 gtk_drag_finish (context, TRUE, FALSE, time);
5254 g_slist_free (uri_list);
5258 ev_window_finalize (GObject *object)
5260 G_OBJECT_CLASS (ev_window_parent_class)->finalize (object);
5262 if (ev_window_n_copies == 0) {
5263 ev_application_shutdown (EV_APP);
5265 ev_window_n_copies--;
5270 ev_window_dispose (GObject *object)
5272 EvWindow *window = EV_WINDOW (object);
5273 EvWindowPrivate *priv = window->priv;
5274 GObject *mpkeys = ev_application_get_media_keys (EV_APP);
5277 g_signal_handlers_disconnect_by_func (mpkeys,
5278 ev_window_media_player_key_pressed,
5283 if (priv->dbus_object_id > 0) {
5284 ev_window_emit_closed (window);
5285 g_dbus_connection_unregister_object (ev_application_get_dbus_connection (EV_APP),
5286 priv->dbus_object_id);
5287 priv->dbus_object_id = 0;
5290 if (priv->dbus_object_path) {
5291 g_free (priv->dbus_object_path);
5292 priv->dbus_object_path = NULL;
5294 #endif /* ENABLE_DBUS */
5296 if (priv->bookmarks) {
5297 g_object_unref (priv->bookmarks);
5298 priv->bookmarks = NULL;
5301 if (priv->metadata) {
5302 g_object_unref (priv->metadata);
5303 priv->metadata = NULL;
5306 if (priv->setup_document_idle > 0) {
5307 g_source_remove (priv->setup_document_idle);
5308 priv->setup_document_idle = 0;
5311 if (priv->monitor) {
5312 g_object_unref (priv->monitor);
5313 priv->monitor = NULL;
5317 ev_window_title_free (priv->title);
5321 if (priv->ui_manager) {
5322 g_object_unref (priv->ui_manager);
5323 priv->ui_manager = NULL;
5326 if (priv->action_group) {
5327 g_object_unref (priv->action_group);
5328 priv->action_group = NULL;
5331 if (priv->view_popup_action_group) {
5332 g_object_unref (priv->view_popup_action_group);
5333 priv->view_popup_action_group = NULL;
5336 if (priv->attachment_popup_action_group) {
5337 g_object_unref (priv->attachment_popup_action_group);
5338 priv->attachment_popup_action_group = NULL;
5341 if (priv->recent_action_group) {
5342 g_object_unref (priv->recent_action_group);
5343 priv->recent_action_group = NULL;
5346 if (priv->bookmarks_action_group) {
5347 g_object_unref (priv->bookmarks_action_group);
5348 priv->bookmarks_action_group = NULL;
5351 if (priv->recent_manager) {
5352 g_signal_handlers_disconnect_by_func (priv->recent_manager,
5353 ev_window_setup_recent,
5355 priv->recent_manager = NULL;
5358 if (priv->settings) {
5359 g_object_unref (priv->settings);
5360 priv->settings = NULL;
5363 if (priv->default_settings) {
5364 g_settings_apply (priv->default_settings);
5365 g_object_unref (priv->default_settings);
5366 priv->default_settings = NULL;
5369 if (priv->lockdown_settings) {
5370 g_object_unref (priv->lockdown_settings);
5371 priv->lockdown_settings = NULL;
5374 priv->recent_ui_id = 0;
5377 g_signal_handlers_disconnect_by_func (priv->model,
5378 ev_window_page_changed_cb,
5380 g_object_unref (priv->model);
5384 if (priv->document) {
5385 g_object_unref (priv->document);
5386 priv->document = NULL;
5390 g_object_unref (priv->view);
5394 if (priv->password_view) {
5395 g_object_unref (priv->password_view);
5396 priv->password_view = NULL;
5399 if (priv->load_job) {
5400 ev_window_clear_load_job (window);
5403 if (priv->reload_job) {
5404 ev_window_clear_reload_job (window);
5407 if (priv->save_job) {
5408 ev_window_clear_save_job (window);
5411 if (priv->thumbnail_job) {
5412 ev_window_clear_thumbnail_job (window);
5415 if (priv->find_job) {
5416 ev_window_clear_find_job (window);
5419 if (priv->local_uri) {
5420 ev_window_clear_local_uri (window);
5421 priv->local_uri = NULL;
5424 ev_window_clear_progress_idle (window);
5425 if (priv->progress_cancellable) {
5426 g_object_unref (priv->progress_cancellable);
5427 priv->progress_cancellable = NULL;
5430 ev_window_close_dialogs (window);
5433 g_object_unref (priv->link);
5438 g_object_unref (priv->image);
5443 g_object_unref (priv->annot);
5447 if (priv->attach_list) {
5448 g_list_foreach (priv->attach_list,
5449 (GFunc) g_object_unref,
5451 g_list_free (priv->attach_list);
5452 priv->attach_list = NULL;
5455 if (priv->find_bar) {
5456 g_signal_handlers_disconnect_by_func
5457 (window->priv->find_bar,
5458 G_CALLBACK (find_bar_close_cb),
5460 priv->find_bar = NULL;
5468 if (priv->search_string) {
5469 g_free (priv->search_string);
5470 priv->search_string = NULL;
5474 g_object_unref (priv->dest);
5478 if (priv->history) {
5479 g_object_unref (priv->history);
5480 priv->history = NULL;
5483 if (priv->print_queue) {
5484 g_queue_free (priv->print_queue);
5485 priv->print_queue = NULL;
5488 G_OBJECT_CLASS (ev_window_parent_class)->dispose (object);
5492 menubar_deactivate_cb (GtkWidget *menubar,
5495 g_signal_handlers_disconnect_by_func (menubar,
5496 G_CALLBACK (menubar_deactivate_cb),
5499 gtk_menu_shell_deselect (GTK_MENU_SHELL (menubar));
5501 update_chrome_visibility (window);
5505 ev_window_key_press_event (GtkWidget *widget,
5508 EvWindow *ev_window = EV_WINDOW (widget);
5509 EvWindowPrivate *priv = ev_window->priv;
5510 gboolean handled = FALSE;
5512 /* Propagate the event to the view first
5513 * It's needed to be able to type in
5514 * annot popups windows
5517 g_object_ref (priv->view);
5518 if (gtk_widget_is_sensitive (priv->view))
5519 handled = gtk_widget_event (priv->view, (GdkEvent*) event);
5520 g_object_unref (priv->view);
5523 if (!handled && !EV_WINDOW_IS_PRESENTATION (ev_window)) {
5524 guint modifier = event->state & gtk_accelerator_get_default_mod_mask ();
5526 if (priv->menubar_accel_keyval != 0 &&
5527 event->keyval == priv->menubar_accel_keyval &&
5528 modifier == priv->menubar_accel_modifier) {
5529 if (!gtk_widget_get_visible (priv->menubar)) {
5530 g_signal_connect (priv->menubar, "deactivate",
5531 G_CALLBACK (menubar_deactivate_cb),
5534 gtk_widget_show (priv->menubar);
5535 gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menubar),
5544 handled = GTK_WIDGET_CLASS (ev_window_parent_class)->key_press_event (widget, event);
5550 ev_window_delete_event (GtkWidget *widget,
5553 return !ev_window_close (EV_WINDOW (widget));
5557 ev_window_class_init (EvWindowClass *ev_window_class)
5559 GObjectClass *g_object_class = G_OBJECT_CLASS (ev_window_class);
5560 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (ev_window_class);
5562 g_object_class->dispose = ev_window_dispose;
5563 g_object_class->finalize = ev_window_finalize;
5565 widget_class->delete_event = ev_window_delete_event;
5566 widget_class->key_press_event = ev_window_key_press_event;
5567 widget_class->screen_changed = ev_window_screen_changed;
5568 widget_class->window_state_event = ev_window_state_event;
5569 widget_class->drag_data_received = ev_window_drag_data_received;
5571 g_type_class_add_private (g_object_class, sizeof (EvWindowPrivate));
5575 static const GtkActionEntry entries[] = {
5576 { "File", NULL, N_("_File") },
5577 { "Edit", NULL, N_("_Edit") },
5578 { "View", NULL, N_("_View") },
5579 { "Go", NULL, N_("_Go") },
5580 { "Bookmarks", NULL, N_("_Bookmarks") },
5581 { "Help", NULL, N_("_Help") },
5584 { "FileOpen", GTK_STOCK_OPEN, N_("_Open…"), "<control>O",
5585 N_("Open an existing document"),
5586 G_CALLBACK (ev_window_cmd_file_open) },
5587 { "FileOpenCopy", NULL, N_("Op_en a Copy"), "<control>N",
5588 N_("Open a copy of the current document in a new window"),
5589 G_CALLBACK (ev_window_cmd_file_open_copy) },
5590 { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy…"), "<control>S",
5591 N_("Save a copy of the current document"),
5592 G_CALLBACK (ev_window_cmd_save_as) },
5593 { "FileOpenContainingFolder", GTK_STOCK_DIRECTORY, N_("Open Containing _Folder"), NULL,
5594 N_("Show the folder which contains this file in the file manager"),
5595 G_CALLBACK (ev_window_cmd_open_containing_folder) },
5596 { "FilePrint", GTK_STOCK_PRINT, N_("_Print…"), "<control>P",
5597 N_("Print this document"),
5598 G_CALLBACK (ev_window_cmd_file_print) },
5599 { "FileProperties", GTK_STOCK_PROPERTIES, N_("P_roperties"), "<alt>Return", NULL,
5600 G_CALLBACK (ev_window_cmd_file_properties) },
5601 { "FileCloseWindow", GTK_STOCK_CLOSE, NULL, "<control>W", NULL,
5602 G_CALLBACK (ev_window_cmd_file_close_window) },
5605 { "EditCopy", GTK_STOCK_COPY, NULL, "<control>C", NULL,
5606 G_CALLBACK (ev_window_cmd_edit_copy) },
5607 { "EditSelectAll", GTK_STOCK_SELECT_ALL, N_("Select _All"), "<control>A", NULL,
5608 G_CALLBACK (ev_window_cmd_edit_select_all) },
5609 { "EditFind", GTK_STOCK_FIND, N_("_Find…"), "<control>F",
5610 N_("Find a word or phrase in the document"),
5611 G_CALLBACK (ev_window_cmd_edit_find) },
5612 { "EditFindNext", NULL, N_("Find Ne_xt"), "<control>G", NULL,
5613 G_CALLBACK (ev_window_cmd_edit_find_next) },
5614 { "EditFindPrevious", NULL, N_("Find Pre_vious"), "<shift><control>G", NULL,
5615 G_CALLBACK (ev_window_cmd_edit_find_previous) },
5616 { "EditToolbar", NULL, N_("T_oolbar"), NULL, NULL,
5617 G_CALLBACK (ev_window_cmd_edit_toolbar) },
5618 { "EditRotateLeft", EV_STOCK_ROTATE_LEFT, N_("Rotate _Left"), "<control>Left", NULL,
5619 G_CALLBACK (ev_window_cmd_edit_rotate_left) },
5620 { "EditRotateRight", EV_STOCK_ROTATE_RIGHT, N_("Rotate _Right"), "<control>Right", NULL,
5621 G_CALLBACK (ev_window_cmd_edit_rotate_right) },
5622 { "EditSaveSettings", NULL, N_("Save Current Settings as _Default"), "<control>T", NULL,
5623 G_CALLBACK (ev_window_cmd_edit_save_settings) },
5627 { "ViewZoomIn", GTK_STOCK_ZOOM_IN, NULL, "<control>plus",
5628 N_("Enlarge the document"),
5629 G_CALLBACK (ev_window_cmd_view_zoom_in) },
5630 { "ViewZoomOut", GTK_STOCK_ZOOM_OUT, NULL, "<control>minus",
5631 N_("Shrink the document"),
5632 G_CALLBACK (ev_window_cmd_view_zoom_out) },
5633 { "ViewReload", GTK_STOCK_REFRESH, N_("_Reload"), "<control>R",
5634 N_("Reload the document"),
5635 G_CALLBACK (ev_window_cmd_view_reload) },
5637 { "ViewAutoscroll", GTK_STOCK_MEDIA_PLAY, N_("Auto_scroll"), NULL, NULL,
5638 G_CALLBACK (ev_window_cmd_view_autoscroll) },
5641 { "GoPreviousPage", GTK_STOCK_GO_UP, N_("_Previous Page"), "<control>Page_Up",
5642 N_("Go to the previous page"),
5643 G_CALLBACK (ev_window_cmd_go_previous_page) },
5644 { "GoNextPage", GTK_STOCK_GO_DOWN, N_("_Next Page"), "<control>Page_Down",
5645 N_("Go to the next page"),
5646 G_CALLBACK (ev_window_cmd_go_next_page) },
5647 { "GoFirstPage", GTK_STOCK_GOTO_TOP, N_("_First Page"), "<control>Home",
5648 N_("Go to the first page"),
5649 G_CALLBACK (ev_window_cmd_go_first_page) },
5650 { "GoLastPage", GTK_STOCK_GOTO_BOTTOM, N_("_Last Page"), "<control>End",
5651 N_("Go to the last page"),
5652 G_CALLBACK (ev_window_cmd_go_last_page) },
5654 /* Bookmarks menu */
5655 { "BookmarksAdd", GTK_STOCK_ADD, N_("_Add Bookmark"), "<control>D",
5656 N_("Add a bookmark for the current page"),
5657 G_CALLBACK (ev_window_cmd_bookmarks_add) },
5660 { "HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL,
5661 G_CALLBACK (ev_window_cmd_help_contents) },
5663 { "HelpAbout", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL,
5664 G_CALLBACK (ev_window_cmd_help_about) },
5667 { "LeaveFullscreen", GTK_STOCK_LEAVE_FULLSCREEN, N_("Leave Fullscreen"), NULL,
5668 N_("Leave fullscreen mode"),
5669 G_CALLBACK (ev_window_cmd_leave_fullscreen) },
5670 { "StartPresentation", EV_STOCK_RUN_PRESENTATION, N_("Start Presentation"), NULL,
5671 N_("Start a presentation"),
5672 G_CALLBACK (ev_window_cmd_start_presentation) },
5675 { "Escape", NULL, "", "Escape", "",
5676 G_CALLBACK (ev_window_cmd_escape) },
5677 { "Slash", GTK_STOCK_FIND, NULL, "slash", NULL,
5678 G_CALLBACK (ev_window_cmd_edit_find) },
5679 { "F3", NULL, "", "F3", NULL,
5680 G_CALLBACK (ev_window_cmd_edit_find_next) },
5681 { "PageDown", NULL, "", "Page_Down", NULL,
5682 G_CALLBACK (ev_window_cmd_scroll_forward) },
5683 { "PageUp", NULL, "", "Page_Up", NULL,
5684 G_CALLBACK (ev_window_cmd_scroll_backward) },
5685 { "Space", NULL, "", "space", NULL,
5686 G_CALLBACK (ev_window_cmd_scroll_forward) },
5687 { "ShiftSpace", NULL, "", "<shift>space", NULL,
5688 G_CALLBACK (ev_window_cmd_scroll_backward) },
5689 { "BackSpace", NULL, "", "BackSpace", NULL,
5690 G_CALLBACK (ev_window_cmd_scroll_backward) },
5691 { "ShiftBackSpace", NULL, "", "<shift>BackSpace", NULL,
5692 G_CALLBACK (ev_window_cmd_scroll_forward) },
5693 { "Return", NULL, "", "Return", NULL,
5694 G_CALLBACK (ev_window_cmd_scroll_forward) },
5695 { "ShiftReturn", NULL, "", "<shift>Return", NULL,
5696 G_CALLBACK (ev_window_cmd_scroll_backward) },
5697 { "p", GTK_STOCK_GO_UP, "", "p", NULL,
5698 G_CALLBACK (ev_window_cmd_go_previous_page) },
5699 { "n", GTK_STOCK_GO_DOWN, "", "n", NULL,
5700 G_CALLBACK (ev_window_cmd_go_next_page) },
5701 { "Plus", GTK_STOCK_ZOOM_IN, NULL, "plus", NULL,
5702 G_CALLBACK (ev_window_cmd_view_zoom_in) },
5703 { "CtrlEqual", GTK_STOCK_ZOOM_IN, NULL, "<control>equal", NULL,
5704 G_CALLBACK (ev_window_cmd_view_zoom_in) },
5705 { "Equal", GTK_STOCK_ZOOM_IN, NULL, "equal", NULL,
5706 G_CALLBACK (ev_window_cmd_view_zoom_in) },
5707 { "Minus", GTK_STOCK_ZOOM_OUT, NULL, "minus", NULL,
5708 G_CALLBACK (ev_window_cmd_view_zoom_out) },
5709 { "FocusPageSelector", NULL, "", "<control>l", NULL,
5710 G_CALLBACK (ev_window_cmd_focus_page_selector) },
5711 { "GoBackwardFast", NULL, "", "<shift>Page_Up", NULL,
5712 G_CALLBACK (ev_window_cmd_go_backward) },
5713 { "GoForwardFast", NULL, "", "<shift>Page_Down", NULL,
5714 G_CALLBACK (ev_window_cmd_go_forward) },
5715 { "KpPlus", GTK_STOCK_ZOOM_IN, NULL, "KP_Add", NULL,
5716 G_CALLBACK (ev_window_cmd_view_zoom_in) },
5717 { "KpMinus", GTK_STOCK_ZOOM_OUT, NULL, "KP_Subtract", NULL,
5718 G_CALLBACK (ev_window_cmd_view_zoom_out) },
5719 { "CtrlKpPlus", GTK_STOCK_ZOOM_IN, NULL, "<control>KP_Add", NULL,
5720 G_CALLBACK (ev_window_cmd_view_zoom_in) },
5721 { "CtrlKpMinus", GTK_STOCK_ZOOM_OUT, NULL, "<control>KP_Subtract", NULL,
5722 G_CALLBACK (ev_window_cmd_view_zoom_out) },
5723 { "CtrlInsert", GTK_STOCK_COPY, NULL, "<control>Insert", NULL,
5724 G_CALLBACK (ev_window_cmd_edit_copy) },
5728 static const GtkToggleActionEntry toggle_entries[] = {
5730 { "ViewToolbar", NULL, N_("_Toolbar"), NULL,
5731 N_("Show or hide the toolbar"),
5732 G_CALLBACK (ev_window_view_toolbar_cb), TRUE },
5733 { "ViewSidebar", GTK_STOCK_INDEX, N_("Side _Pane"), "F9",
5734 N_("Show or hide the side pane"),
5735 G_CALLBACK (ev_window_view_sidebar_cb), TRUE },
5736 { "ViewContinuous", EV_STOCK_VIEW_CONTINUOUS, N_("_Continuous"), NULL,
5737 N_("Show the entire document"),
5738 G_CALLBACK (ev_window_cmd_continuous), TRUE },
5739 { "ViewDual", EV_STOCK_VIEW_DUAL, N_("_Dual"), NULL,
5740 N_("Show two pages at once"),
5741 G_CALLBACK (ev_window_cmd_dual), FALSE },
5742 { "ViewFullscreen", GTK_STOCK_FULLSCREEN, N_("_Fullscreen"), "F11",
5743 N_("Expand the window to fill the screen"),
5744 G_CALLBACK (ev_window_cmd_view_fullscreen) },
5745 { "ViewPresentation", EV_STOCK_RUN_PRESENTATION, N_("Pre_sentation"), "F5",
5746 N_("Run document as a presentation"),
5747 G_CALLBACK (ev_window_cmd_view_presentation) },
5748 { "ViewBestFit", EV_STOCK_ZOOM_PAGE, N_("_Best Fit"), NULL,
5749 N_("Make the current document fill the window"),
5750 G_CALLBACK (ev_window_cmd_view_best_fit) },
5751 { "ViewPageWidth", EV_STOCK_ZOOM_WIDTH, N_("Fit Page _Width"), NULL,
5752 N_("Make the current document fill the window width"),
5753 G_CALLBACK (ev_window_cmd_view_page_width) },
5754 { "ViewInvertedColors", EV_STOCK_INVERTED_COLORS, N_("_Inverted Colors"), "<control>I",
5755 N_("Show page contents with the colors inverted"),
5756 G_CALLBACK (ev_window_cmd_view_inverted_colors) },
5760 /* Popups specific items */
5761 static const GtkActionEntry view_popup_entries [] = {
5763 { "OpenLink", GTK_STOCK_OPEN, N_("_Open Link"), NULL,
5764 NULL, G_CALLBACK (ev_view_popup_cmd_open_link) },
5765 { "GoLink", GTK_STOCK_GO_FORWARD, N_("_Go To"), NULL,
5766 NULL, G_CALLBACK (ev_view_popup_cmd_open_link) },
5767 { "OpenLinkNewWindow", NULL, N_("Open in New _Window"), NULL,
5768 NULL, G_CALLBACK (ev_view_popup_cmd_open_link_new_window) },
5769 { "CopyLinkAddress", NULL, N_("_Copy Link Address"), NULL,
5770 NULL, G_CALLBACK (ev_view_popup_cmd_copy_link_address) },
5771 { "SaveImageAs", NULL, N_("_Save Image As…"), NULL,
5772 NULL, G_CALLBACK (ev_view_popup_cmd_save_image_as) },
5773 { "CopyImage", NULL, N_("Copy _Image"), NULL,
5774 NULL, G_CALLBACK (ev_view_popup_cmd_copy_image) },
5775 { "AnnotProperties", NULL, N_("Annotation Properties…"), NULL,
5776 NULL, G_CALLBACK (ev_view_popup_cmd_annot_properties) }
5779 static const GtkActionEntry attachment_popup_entries [] = {
5780 { "OpenAttachment", GTK_STOCK_OPEN, N_("_Open Attachment"), NULL,
5781 NULL, G_CALLBACK (ev_attachment_popup_cmd_open_attachment) },
5782 { "SaveAttachmentAs", GTK_STOCK_SAVE_AS, N_("_Save Attachment As…"), NULL,
5783 NULL, G_CALLBACK (ev_attachment_popup_cmd_save_attachment_as) },
5787 sidebar_links_link_activated_cb (EvSidebarLinks *sidebar_links, EvLink *link, EvWindow *window)
5789 ev_view_handle_link (EV_VIEW (window->priv->view), link);
5793 activate_link_cb (EvPageAction *page_action, EvLink *link, EvWindow *window)
5795 ev_view_handle_link (EV_VIEW (window->priv->view), link);
5796 gtk_widget_grab_focus (window->priv->view);
5800 navigation_action_activate_link_cb (EvNavigationAction *action, EvLink *link, EvWindow *window)
5803 ev_view_handle_link (EV_VIEW (window->priv->view), link);
5804 gtk_widget_grab_focus (window->priv->view);
5808 sidebar_layers_visibility_changed (EvSidebarLayers *layers,
5811 ev_view_reload (EV_VIEW (window->priv->view));
5815 sidebar_annots_annot_activated_cb (EvSidebarAnnotations *sidebar_annots,
5816 EvMapping *annot_mapping,
5819 ev_view_focus_annotation (EV_VIEW (window->priv->view), annot_mapping);
5823 sidebar_annots_begin_annot_add (EvSidebarAnnotations *sidebar_annots,
5824 EvAnnotationType annot_type,
5827 ev_view_begin_add_annotation (EV_VIEW (window->priv->view), annot_type);
5831 view_annot_added (EvView *view,
5832 EvAnnotation *annot,
5835 ev_sidebar_annotations_annot_added (EV_SIDEBAR_ANNOTATIONS (window->priv->sidebar_annots),
5840 sidebar_annots_annot_add_cancelled (EvSidebarAnnotations *sidebar_annots,
5843 ev_view_cancel_add_annotation (EV_VIEW (window->priv->view));
5847 register_custom_actions (EvWindow *window, GtkActionGroup *group)
5851 action = g_object_new (EV_TYPE_PAGE_ACTION,
5852 "name", PAGE_SELECTOR_ACTION,
5854 "tooltip", _("Select Page"),
5855 "icon_name", "text-x-generic",
5856 "visible_overflown", FALSE,
5858 ev_page_action_set_model (EV_PAGE_ACTION (action),
5859 window->priv->model);
5860 g_signal_connect (action, "activate_link",
5861 G_CALLBACK (activate_link_cb), window);
5862 gtk_action_group_add_action (group, action);
5863 g_object_unref (action);
5865 action = g_object_new (EPHY_TYPE_ZOOM_ACTION,
5866 "name", ZOOM_CONTROL_ACTION,
5868 "stock_id", EV_STOCK_ZOOM,
5869 "tooltip", _("Adjust the zoom level"),
5872 g_signal_connect (action, "zoom_to_level",
5873 G_CALLBACK (zoom_control_changed_cb), window);
5874 gtk_action_group_add_action (group, action);
5875 g_object_unref (action);
5877 action = g_object_new (EV_TYPE_NAVIGATION_ACTION,
5878 "name", NAVIGATION_ACTION,
5879 "label", _("Navigation"),
5880 "is_important", TRUE,
5881 "short_label", _("Back"),
5882 "stock_id", GTK_STOCK_GO_DOWN,
5883 /*translators: this is the history action*/
5884 "tooltip", _("Move across visited pages"),
5886 g_signal_connect (action, "activate_link",
5887 G_CALLBACK (navigation_action_activate_link_cb), window);
5888 gtk_action_group_add_action (group, action);
5889 g_object_unref (action);
5891 action = g_object_new (EV_TYPE_OPEN_RECENT_ACTION,
5892 "name", "FileOpenRecent",
5893 "label", _("_Open…"),
5894 "tooltip", _("Open an existing document"),
5895 "stock_id", GTK_STOCK_OPEN,
5897 g_signal_connect (action, "activate",
5898 G_CALLBACK (ev_window_cmd_file_open), window);
5899 g_signal_connect (action, "item_activated",
5900 G_CALLBACK (ev_window_open_recent_action_item_activated),
5902 gtk_action_group_add_action (group, action);
5903 g_object_unref (action);
5907 set_action_properties (GtkActionGroup *action_group)
5911 action = gtk_action_group_get_action (action_group, "FileOpenContainingFolder");
5912 /*translators: this is the label for toolbar button*/
5913 g_object_set (action, "short_label", _("Open Folder"), NULL);
5915 action = gtk_action_group_get_action (action_group, "GoPreviousPage");
5916 g_object_set (action, "is-important", TRUE, NULL);
5917 /*translators: this is the label for toolbar button*/
5918 g_object_set (action, "short_label", _("Previous"), NULL);
5920 action = gtk_action_group_get_action (action_group, "GoNextPage");
5921 g_object_set (action, "is-important", TRUE, NULL);
5922 /*translators: this is the label for toolbar button*/
5923 g_object_set (action, "short_label", _("Next"), NULL);
5925 action = gtk_action_group_get_action (action_group, "ViewZoomIn");
5926 /*translators: this is the label for toolbar button*/
5927 g_object_set (action, "short_label", _("Zoom In"), NULL);
5929 action = gtk_action_group_get_action (action_group, "ViewZoomOut");
5930 /*translators: this is the label for toolbar button*/
5931 g_object_set (action, "short_label", _("Zoom Out"), NULL);
5933 action = gtk_action_group_get_action (action_group, "ViewBestFit");
5934 /*translators: this is the label for toolbar button*/
5935 g_object_set (action, "short_label", _("Best Fit"), NULL);
5937 action = gtk_action_group_get_action (action_group, "ViewPageWidth");
5938 /*translators: this is the label for toolbar button*/
5939 g_object_set (action, "short_label", _("Fit Width"), NULL);
5941 action = gtk_action_group_get_action (action_group, "LeaveFullscreen");
5942 g_object_set (action, "is-important", TRUE, NULL);
5946 sidebar_widget_model_set (EvSidebarLinks *ev_sidebar_links,
5948 EvWindow *ev_window)
5950 GtkTreeModel *model;
5953 g_object_get (G_OBJECT (ev_sidebar_links),
5957 action = gtk_action_group_get_action (ev_window->priv->action_group, PAGE_SELECTOR_ACTION);
5958 ev_page_action_set_links_model (EV_PAGE_ACTION (action), model);
5959 g_object_unref (model);
5963 view_actions_focus_in_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *window)
5968 keys = ev_application_get_media_keys (EV_APP);
5969 ev_media_player_keys_focused (EV_MEDIA_PLAYER_KEYS (keys));
5970 #endif /* ENABLE_DBUS */
5972 update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, FALSE);
5973 ev_window_set_action_sensitive (window, "ViewToolbar", TRUE);
5975 ev_window_set_view_accels_sensitivity (window, TRUE);
5977 update_chrome_visibility (window);
5983 view_actions_focus_out_cb (GtkWidget *widget, GdkEventFocus *event, EvWindow *window)
5985 ev_window_set_view_accels_sensitivity (window, FALSE);
5991 sidebar_page_main_widget_update_cb (GObject *ev_sidebar_page,
5993 EvWindow *ev_window)
5997 g_object_get (ev_sidebar_page, "main_widget", &widget, NULL);
5999 if (widget != NULL) {
6000 g_signal_connect_object (widget, "focus_in_event",
6001 G_CALLBACK (view_actions_focus_in_cb),
6003 g_signal_connect_object (widget, "focus_out_event",
6004 G_CALLBACK (view_actions_focus_out_cb),
6006 g_object_unref (widget);
6011 window_state_event_cb (EvWindow *window, GdkEventWindowState *event, gpointer dummy)
6013 if (!(event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
6016 maximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED;
6017 if (window->priv->metadata && !ev_window_is_empty (window))
6018 ev_metadata_set_boolean (window->priv->metadata, "window_maximized", maximized);
6025 window_configure_event_cb (EvWindow *window, GdkEventConfigure *event, gpointer dummy)
6027 GdkWindowState state;
6028 gdouble document_width, document_height;
6030 if (!window->priv->metadata)
6033 state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (window)));
6035 if (!(state & GDK_WINDOW_STATE_FULLSCREEN)) {
6036 if (window->priv->document) {
6037 ev_document_get_max_page_size (window->priv->document,
6038 &document_width, &document_height);
6039 g_settings_set (window->priv->default_settings, "window-ratio", "(dd)",
6040 (double)event->width / document_width,
6041 (double)event->height / document_height);
6043 ev_metadata_set_int (window->priv->metadata, "window_x", event->x);
6044 ev_metadata_set_int (window->priv->metadata, "window_y", event->y);
6045 ev_metadata_set_int (window->priv->metadata, "window_width", event->width);
6046 ev_metadata_set_int (window->priv->metadata, "window_height", event->height);
6054 launch_action (EvWindow *window, EvLinkAction *action)
6056 const char *filename = ev_link_action_get_filename (action);
6059 GList file_list = {NULL};
6060 GAppLaunchContext *context;
6061 GError *error = NULL;
6063 if (filename == NULL)
6066 if (g_path_is_absolute (filename)) {
6067 file = g_file_new_for_path (filename);
6072 dir = g_path_get_dirname (window->priv->uri);
6073 base_file = g_file_new_for_uri (dir);
6076 file = g_file_resolve_relative_path (base_file, filename);
6077 g_object_unref (base_file);
6080 app_info = g_file_query_default_handler (file, NULL, &error);
6082 ev_window_error_message (window, error,
6084 _("Unable to launch external application."));
6085 g_object_unref (file);
6086 g_error_free (error);
6091 context = G_APP_LAUNCH_CONTEXT (gdk_app_launch_context_new ());
6092 gdk_app_launch_context_set_screen (GDK_APP_LAUNCH_CONTEXT (context),
6093 gtk_window_get_screen (GTK_WINDOW (window)));
6094 gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context),
6095 gtk_get_current_event_time ());
6097 file_list.data = file;
6098 if (!g_app_info_launch (app_info, &file_list, context, &error)) {
6099 ev_window_error_message (window, error,
6101 _("Unable to launch external application."));
6102 g_error_free (error);
6105 g_object_unref (app_info);
6106 g_object_unref (file);
6107 /* FIXMEchpe: unref launch context? */
6109 /* According to the PDF spec filename can be an executable. I'm not sure
6110 allowing to launch executables is a good idea though. -- marco */
6114 launch_external_uri (EvWindow *window, EvLinkAction *action)
6116 const gchar *uri = ev_link_action_get_uri (action);
6117 GError *error = NULL;
6119 GAppLaunchContext *context;
6121 context = G_APP_LAUNCH_CONTEXT (gdk_app_launch_context_new ());
6122 gdk_app_launch_context_set_screen (GDK_APP_LAUNCH_CONTEXT (context),
6123 gtk_window_get_screen (GTK_WINDOW (window)));
6124 gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context),
6125 gtk_get_current_event_time ());
6127 if (!g_strstr_len (uri, strlen (uri), "://") &&
6128 !g_str_has_prefix (uri, "mailto:")) {
6131 /* Not a valid uri, assume http if it starts with www */
6132 if (g_str_has_prefix (uri, "www.")) {
6133 new_uri = g_strdup_printf ("http://%s", uri);
6135 GFile *file, *parent;
6137 file = g_file_new_for_uri (window->priv->uri);
6138 parent = g_file_get_parent (file);
6139 g_object_unref (file);
6141 gchar *parent_uri = g_file_get_uri (parent);
6143 new_uri = g_build_filename (parent_uri, uri, NULL);
6144 g_free (parent_uri);
6145 g_object_unref (parent);
6147 new_uri = g_strdup_printf ("file:///%s", uri);
6150 ret = g_app_info_launch_default_for_uri (new_uri, context, &error);
6153 ret = g_app_info_launch_default_for_uri (uri, context, &error);
6157 ev_window_error_message (window, error,
6158 "%s", _("Unable to open external link"));
6159 g_error_free (error);
6162 /* FIXMEchpe: unref launch context? */
6166 open_remote_link (EvWindow *window, EvLinkAction *action)
6171 dir = g_path_get_dirname (window->priv->uri);
6173 uri = g_build_filename (dir, ev_link_action_get_filename (action),
6177 ev_application_open_uri_at_dest (EV_APP, uri,
6178 gtk_window_get_screen (GTK_WINDOW (window)),
6179 ev_link_action_get_dest (action),
6182 gtk_get_current_event_time ());
6188 do_action_named (EvWindow *window, EvLinkAction *action)
6190 const gchar *name = ev_link_action_get_name (action);
6192 if (g_ascii_strcasecmp (name, "FirstPage") == 0) {
6193 ev_window_cmd_go_first_page (NULL, window);
6194 } else if (g_ascii_strcasecmp (name, "PrevPage") == 0) {
6195 ev_window_cmd_go_previous_page (NULL, window);
6196 } else if (g_ascii_strcasecmp (name, "NextPage") == 0) {
6197 ev_window_cmd_go_next_page (NULL, window);
6198 } else if (g_ascii_strcasecmp (name, "LastPage") == 0) {
6199 ev_window_cmd_go_last_page (NULL, window);
6200 } else if (g_ascii_strcasecmp (name, "GoToPage") == 0) {
6201 ev_window_cmd_focus_page_selector (NULL, window);
6202 } else if (g_ascii_strcasecmp (name, "Find") == 0) {
6203 ev_window_cmd_edit_find (NULL, window);
6204 } else if (g_ascii_strcasecmp (name, "Close") == 0) {
6205 ev_window_cmd_file_close_window (NULL, window);
6206 } else if (g_ascii_strcasecmp (name, "Print") == 0) {
6207 ev_window_cmd_file_print (NULL, window);
6209 g_warning ("Unimplemented named action: %s, please post a "
6210 "bug report in Evince bugzilla "
6211 "(http://bugzilla.gnome.org) with a testcase.",
6217 view_external_link_cb (EvView *view, EvLinkAction *action, EvWindow *window)
6219 switch (ev_link_action_get_action_type (action)) {
6220 case EV_LINK_ACTION_TYPE_GOTO_DEST: {
6223 dest = ev_link_action_get_dest (action);
6227 ev_window_open_copy_at_dest (window, dest);
6230 case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
6231 launch_external_uri (window, action);
6233 case EV_LINK_ACTION_TYPE_LAUNCH:
6234 launch_action (window, action);
6236 case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
6237 open_remote_link (window, action);
6239 case EV_LINK_ACTION_TYPE_NAMED:
6240 do_action_named (window, action);
6243 g_assert_not_reached ();
6248 ev_view_popup_cmd_open_link (GtkAction *action, EvWindow *window)
6250 ev_view_handle_link (EV_VIEW (window->priv->view), window->priv->link);
6254 ev_view_popup_cmd_open_link_new_window (GtkAction *action, EvWindow *window)
6256 EvLinkAction *ev_action = NULL;
6259 ev_action = ev_link_get_action (window->priv->link);
6263 dest = ev_link_action_get_dest (ev_action);
6267 ev_window_open_copy_at_dest (window, dest);
6271 ev_view_popup_cmd_copy_link_address (GtkAction *action, EvWindow *window)
6273 EvLinkAction *ev_action;
6275 ev_action = ev_link_get_action (window->priv->link);
6279 ev_view_copy_link_address (EV_VIEW (window->priv->view),
6285 image_save_dialog_response_cb (GtkWidget *fc,
6287 EvWindow *ev_window)
6291 GError *error = NULL;
6297 GdkPixbufFormat *format;
6298 GtkFileFilter *filter;
6300 if (response_id != GTK_RESPONSE_OK) {
6301 gtk_widget_destroy (fc);
6305 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
6306 filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (fc));
6307 format = g_object_get_data (G_OBJECT (filter), "pixbuf-format");
6309 if (format == NULL) {
6310 format = get_gdk_pixbuf_format_by_extension (uri);
6313 if (format == NULL && g_strrstr (uri, ".") == NULL) {
6314 /* no extension found and no extension provided within uri */
6315 format = get_gdk_pixbuf_format_by_extension (".png");
6316 if (format == NULL) {
6317 /* no .png support, try .jpeg */
6318 format = get_gdk_pixbuf_format_by_extension (".jpeg");
6322 if (format == NULL) {
6323 ev_window_error_message (ev_window, NULL,
6325 _("Couldn't find appropriate format to save image"));
6327 gtk_widget_destroy (fc);
6332 extensions = gdk_pixbuf_format_get_extensions (format);
6333 if (!g_str_has_suffix (uri, extensions[0])) {
6334 gchar *uri_extension;
6336 uri_extension = g_strconcat (uri, ".", extensions[0], NULL);
6337 target_file = g_file_new_for_uri (uri_extension);
6338 g_free (uri_extension);
6340 target_file = g_file_new_for_uri (uri);
6342 g_strfreev (extensions);
6345 is_native = g_file_is_native (target_file);
6347 filename = g_file_get_path (target_file);
6349 /* Create a temporary local file to save to */
6350 if (ev_mkstemp ("saveimage.XXXXXX", &filename, &error) == -1)
6354 ev_document_doc_mutex_lock ();
6355 pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (ev_window->priv->document),
6356 ev_window->priv->image);
6357 ev_document_doc_mutex_unlock ();
6359 file_format = gdk_pixbuf_format_get_name (format);
6360 gdk_pixbuf_save (pixbuf, filename, file_format, &error, NULL);
6361 g_free (file_format);
6362 g_object_unref (pixbuf);
6366 ev_window_error_message (ev_window, error,
6367 "%s", _("The image could not be saved."));
6368 g_error_free (error);
6370 g_object_unref (target_file);
6371 gtk_widget_destroy (fc);
6379 source_file = g_file_new_for_path (filename);
6381 ev_window_save_remote (ev_window, EV_SAVE_IMAGE,
6382 source_file, target_file);
6383 g_object_unref (source_file);
6387 g_object_unref (target_file);
6388 gtk_widget_destroy (fc);
6392 ev_view_popup_cmd_save_image_as (GtkAction *action, EvWindow *window)
6396 if (!window->priv->image)
6399 fc = gtk_file_chooser_dialog_new (_("Save Image"),
6400 GTK_WINDOW (window),
6401 GTK_FILE_CHOOSER_ACTION_SAVE,
6403 GTK_RESPONSE_CANCEL,
6404 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
6407 gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK);
6408 gtk_dialog_set_alternative_button_order (GTK_DIALOG (fc),
6410 GTK_RESPONSE_CANCEL,
6413 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (fc), FALSE);
6414 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE);
6416 file_chooser_dialog_add_writable_pixbuf_formats (GTK_FILE_CHOOSER (fc));
6418 g_signal_connect (fc, "response",
6419 G_CALLBACK (image_save_dialog_response_cb),
6422 gtk_widget_show (fc);
6426 ev_view_popup_cmd_copy_image (GtkAction *action, EvWindow *window)
6428 GtkClipboard *clipboard;
6431 if (!window->priv->image)
6434 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window),
6435 GDK_SELECTION_CLIPBOARD);
6436 ev_document_doc_mutex_lock ();
6437 pixbuf = ev_document_images_get_image (EV_DOCUMENT_IMAGES (window->priv->document),
6438 window->priv->image);
6439 ev_document_doc_mutex_unlock ();
6441 gtk_clipboard_set_image (clipboard, pixbuf);
6442 g_object_unref (pixbuf);
6446 ev_view_popup_cmd_annot_properties (GtkAction *action,
6449 const gchar *author;
6452 gboolean popup_is_open;
6453 EvAnnotationPropertiesDialog *dialog;
6454 EvAnnotation *annot = window->priv->annot;
6455 EvAnnotationsSaveMask mask = EV_ANNOTATIONS_SAVE_NONE;
6460 dialog = EV_ANNOTATION_PROPERTIES_DIALOG (ev_annotation_properties_dialog_new_with_annotation (window->priv->annot));
6461 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_APPLY) {
6462 gtk_widget_destroy (GTK_WIDGET (dialog));
6467 /* Set annotations changes */
6468 author = ev_annotation_properties_dialog_get_author (dialog);
6469 if (ev_annotation_markup_set_label (EV_ANNOTATION_MARKUP (annot), author))
6470 mask |= EV_ANNOTATIONS_SAVE_LABEL;
6472 ev_annotation_properties_dialog_get_color (dialog, &color);
6473 if (ev_annotation_set_color (annot, &color))
6474 mask |= EV_ANNOTATIONS_SAVE_COLOR;
6476 opacity = ev_annotation_properties_dialog_get_opacity (dialog);
6477 if (ev_annotation_markup_set_opacity (EV_ANNOTATION_MARKUP (annot), opacity))
6478 mask |= EV_ANNOTATIONS_SAVE_OPACITY;
6480 popup_is_open = ev_annotation_properties_dialog_get_popup_is_open (dialog);
6481 if (ev_annotation_markup_set_popup_is_open (EV_ANNOTATION_MARKUP (annot), popup_is_open))
6482 mask |= EV_ANNOTATIONS_SAVE_POPUP_IS_OPEN;
6484 if (EV_IS_ANNOTATION_TEXT (annot)) {
6485 EvAnnotationTextIcon icon;
6487 icon = ev_annotation_properties_dialog_get_text_icon (dialog);
6488 if (ev_annotation_text_set_icon (EV_ANNOTATION_TEXT (annot), icon))
6489 mask |= EV_ANNOTATIONS_SAVE_TEXT_ICON;
6492 if (mask != EV_ANNOTATIONS_SAVE_NONE) {
6493 ev_document_doc_mutex_lock ();
6494 ev_document_annotations_save_annotation (EV_DOCUMENT_ANNOTATIONS (window->priv->document),
6495 window->priv->annot,
6497 ev_document_doc_mutex_unlock ();
6499 /* FIXME: update annot region only */
6500 ev_view_reload (EV_VIEW (window->priv->view));
6503 gtk_widget_destroy (GTK_WIDGET (dialog));
6507 ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window)
6512 if (!window->priv->attach_list)
6515 screen = gtk_window_get_screen (GTK_WINDOW (window));
6517 for (l = window->priv->attach_list; l && l->data; l = g_list_next (l)) {
6518 EvAttachment *attachment;
6519 GError *error = NULL;
6521 attachment = (EvAttachment *) l->data;
6523 ev_attachment_open (attachment, screen, gtk_get_current_event_time (), &error);
6526 ev_window_error_message (window, error,
6527 "%s", _("Unable to open attachment"));
6528 g_error_free (error);
6534 attachment_save_dialog_response_cb (GtkWidget *fc,
6536 EvWindow *ev_window)
6541 GtkFileChooserAction fc_action;
6545 if (response_id != GTK_RESPONSE_OK) {
6546 gtk_widget_destroy (fc);
6550 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc));
6551 target_file = g_file_new_for_uri (uri);
6552 g_object_get (G_OBJECT (fc), "action", &fc_action, NULL);
6553 is_dir = (fc_action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
6554 is_native = g_file_is_native (target_file);
6556 for (l = ev_window->priv->attach_list; l && l->data; l = g_list_next (l)) {
6557 EvAttachment *attachment;
6558 GFile *save_to = NULL;
6559 GError *error = NULL;
6561 attachment = (EvAttachment *) l->data;
6565 save_to = g_file_get_child (target_file,
6566 /* FIXMEchpe: file name encoding! */
6567 ev_attachment_get_name (attachment));
6569 save_to = g_object_ref (target_file);
6572 save_to = ev_mkstemp_file ("saveattachment.XXXXXX", &error);
6576 ev_attachment_save (attachment, save_to, &error);
6579 ev_window_error_message (ev_window, error,
6580 "%s", _("The attachment could not be saved."));
6581 g_error_free (error);
6582 g_object_unref (save_to);
6591 dest_file = g_file_get_child (target_file,
6592 ev_attachment_get_name (attachment));
6594 dest_file = g_object_ref (target_file);
6597 ev_window_save_remote (ev_window, EV_SAVE_ATTACHMENT,
6598 save_to, dest_file);
6600 g_object_unref (dest_file);
6603 g_object_unref (save_to);
6607 g_object_unref (target_file);
6609 gtk_widget_destroy (fc);
6613 ev_attachment_popup_cmd_save_attachment_as (GtkAction *action, EvWindow *window)
6616 EvAttachment *attachment = NULL;
6618 if (!window->priv->attach_list)
6621 if (g_list_length (window->priv->attach_list) == 1)
6622 attachment = (EvAttachment *) window->priv->attach_list->data;
6624 fc = gtk_file_chooser_dialog_new (
6625 _("Save Attachment"),
6626 GTK_WINDOW (window),
6627 attachment ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
6629 GTK_RESPONSE_CANCEL,
6630 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
6633 gtk_dialog_set_default_response (GTK_DIALOG (fc), GTK_RESPONSE_OK);
6634 gtk_dialog_set_alternative_button_order (GTK_DIALOG (fc),
6636 GTK_RESPONSE_CANCEL,
6639 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE);
6640 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (fc), FALSE);
6643 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (fc),
6644 ev_attachment_get_name (attachment));
6646 g_signal_connect (fc, "response",
6647 G_CALLBACK (attachment_save_dialog_response_cb),
6650 gtk_widget_show (fc);
6654 ev_window_media_player_key_pressed (EvWindow *window,
6658 if (!gtk_window_is_active (GTK_WINDOW (window)))
6661 /* Note how Previous/Next only go to the
6662 * next/previous page despite their icon telling you
6663 * they should go to the beginning/end.
6665 * There's very few keyboards with FFW/RWD though,
6666 * so we stick the most useful keybinding on the most
6669 if (strcmp (key, "Play") == 0) {
6670 ev_window_run_presentation (window);
6671 } else if (strcmp (key, "Previous") == 0) {
6672 ev_window_cmd_go_previous_page (NULL, window);
6673 } else if (strcmp (key, "Next") == 0) {
6674 ev_window_cmd_go_next_page (NULL, window);
6675 } else if (strcmp (key, "FastForward") == 0) {
6676 ev_window_cmd_go_last_page (NULL, window);
6677 } else if (strcmp (key, "Rewind") == 0) {
6678 ev_window_cmd_go_first_page (NULL, window);
6682 static EggToolbarsModel *
6683 get_toolbars_model (void)
6685 EggToolbarsModel *toolbars_model;
6686 gchar *toolbars_file;
6687 gchar *toolbars_path;
6690 toolbars_model = egg_toolbars_model_new ();
6692 toolbars_file = g_build_filename (ev_application_get_dot_dir (EV_APP, FALSE),
6693 "evince_toolbar.xml", NULL);
6694 toolbars_path = g_build_filename (ev_application_get_data_dir (EV_APP),
6695 "evince-toolbar.xml", NULL);
6696 egg_toolbars_model_load_names (toolbars_model, toolbars_path);
6698 if (!egg_toolbars_model_load_toolbars (toolbars_model, toolbars_file)) {
6699 egg_toolbars_model_load_toolbars (toolbars_model, toolbars_path);
6700 goto skip_conversion;
6703 /* Open item doesn't exist anymore,
6704 * convert it to OpenRecent for compatibility
6706 for (i = 0; i < egg_toolbars_model_n_items (toolbars_model, 0); i++) {
6709 item = egg_toolbars_model_item_nth (toolbars_model, 0, i);
6710 if (g_ascii_strcasecmp (item, "FileOpen") == 0) {
6711 egg_toolbars_model_remove_item (toolbars_model, 0, i);
6712 egg_toolbars_model_add_item (toolbars_model, 0, i,
6714 egg_toolbars_model_save_toolbars (toolbars_model, toolbars_file, "1.0");
6720 g_free (toolbars_file);
6721 g_free (toolbars_path);
6723 egg_toolbars_model_set_flags (toolbars_model, 0, EGG_TB_MODEL_NOT_REMOVABLE);
6725 return toolbars_model;
6730 ev_window_sync_source (EvWindow *window,
6733 GDBusConnection *connection;
6734 GError *error = NULL;
6739 if (window->priv->dbus_object_id <= 0)
6742 connection = ev_application_get_dbus_connection (EV_APP);
6746 timestamp = gtk_get_current_event_time ();
6747 if (g_path_is_absolute (link->filename)) {
6748 input_gfile = g_file_new_for_path (link->filename);
6750 GFile *gfile, *parent_gfile;
6752 gfile = g_file_new_for_uri (window->priv->uri);
6753 parent_gfile = g_file_get_parent (gfile);
6755 /* parent_gfile should never be NULL */
6756 if (parent_gfile == NULL) {
6757 g_printerr ("Document URI is '/'\n");
6761 input_gfile = g_file_get_child (parent_gfile, link->filename);
6762 g_object_unref (parent_gfile);
6763 g_object_unref (gfile);
6766 uri_input = g_file_get_uri (input_gfile);
6767 g_object_unref (input_gfile);
6769 g_dbus_connection_emit_signal (connection,
6771 window->priv->dbus_object_path,
6772 EV_WINDOW_DBUS_INTERFACE,
6774 g_variant_new ("(s(ii)u)",
6782 g_printerr ("Failed to emit DBus signal SyncSource: %s\n",
6784 g_error_free (error);
6789 ev_window_emit_closed (EvWindow *window)
6791 GDBusConnection *connection;
6792 GError *error = NULL;
6794 if (window->priv->dbus_object_id <= 0)
6797 connection = ev_application_get_dbus_connection (EV_APP);
6801 g_dbus_connection_emit_signal (connection,
6803 window->priv->dbus_object_path,
6804 EV_WINDOW_DBUS_INTERFACE,
6809 g_printerr ("Failed to emit DBus signal Closed: %s\n",
6811 g_error_free (error);
6816 /* If this is the last window call g_dbus_connection_flush_sync()
6817 * to make sure the signal is emitted.
6819 if (ev_application_get_n_windows (EV_APP) == 1)
6820 g_dbus_connection_flush_sync (connection, NULL, NULL);
6824 ev_window_emit_doc_loaded (EvWindow *window)
6826 GDBusConnection *connection;
6827 GError *error = NULL;
6829 if (window->priv->dbus_object_id <= 0)
6832 connection = ev_application_get_dbus_connection (EV_APP);
6836 g_dbus_connection_emit_signal (connection,
6838 window->priv->dbus_object_path,
6839 EV_WINDOW_DBUS_INTERFACE,
6841 g_variant_new("(s)", window->priv->uri),
6844 g_printerr ("Failed to emit DBus signal DocumentLoaded: %s\n",
6846 g_error_free (error);
6853 method_call_cb (GDBusConnection *connection,
6854 const gchar *sender,
6855 const gchar *object_path,
6856 const gchar *interface_name,
6857 const gchar *method_name,
6858 GVariant *parameters,
6859 GDBusMethodInvocation *invocation,
6862 EvWindow *window = EV_WINDOW (user_data);
6864 if (g_strcmp0 (method_name, "SyncView") != 0)
6867 if (window->priv->document && ev_document_has_synctex (window->priv->document)) {
6871 g_variant_get (parameters, "(&s(ii)u)", &link.filename, &link.line, &link.col, ×tamp);
6872 ev_view_highlight_forward_search (EV_VIEW (window->priv->view), &link);
6873 gtk_window_present_with_time (GTK_WINDOW (window), timestamp);
6876 g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
6879 static const char introspection_xml[] =
6881 "<interface name='org.gnome.evince.Window'>"
6882 "<method name='SyncView'>"
6883 "<arg type='s' name='source_file' direction='in'/>"
6884 "<arg type='(ii)' name='source_point' direction='in'/>"
6885 "<arg type='u' name='timestamp' direction='in'/>"
6887 "<signal name='SyncSource'>"
6888 "<arg type='s' name='source_file' direction='out'/>"
6889 "<arg type='(ii)' name='source_point' direction='out'/>"
6890 "<arg type='u' name='timestamp' direction='out'/>"
6892 "<signal name='Closed'/>"
6893 "<signal name='DocumentLoaded'>"
6894 "<arg type='s' name='uri' direction='out'/>"
6899 static const GDBusInterfaceVTable interface_vtable = {
6905 static GDBusNodeInfo *introspection_data;
6906 #endif /* ENABLE_DBUS */
6909 ev_window_init (EvWindow *ev_window)
6911 GtkActionGroup *action_group;
6912 GtkAccelGroup *accel_group;
6913 GError *error = NULL;
6914 GtkWidget *sidebar_widget;
6915 GtkWidget *menuitem;
6916 EggToolbarsModel *toolbars_model;
6920 GDBusConnection *connection;
6921 static gint window_id = 0;
6924 g_signal_connect (ev_window, "configure_event",
6925 G_CALLBACK (window_configure_event_cb), NULL);
6926 g_signal_connect (ev_window, "window_state_event",
6927 G_CALLBACK (window_state_event_cb), NULL);
6929 ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window);
6932 connection = ev_application_get_dbus_connection (EV_APP);
6934 if (!introspection_data) {
6935 introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, &error);
6936 if (error) g_warning ("%s\n", error->message);
6938 g_assert (introspection_data != NULL);
6940 ev_window->priv->dbus_object_path = g_strdup_printf (EV_WINDOW_DBUS_OBJECT_PATH, window_id++);
6941 ev_window->priv->dbus_object_id =
6942 g_dbus_connection_register_object (connection,
6943 ev_window->priv->dbus_object_path,
6944 introspection_data->interfaces[0],
6948 if (ev_window->priv->dbus_object_id == 0) {
6949 g_printerr ("Failed to register bus object %s: %s\n",
6950 ev_window->priv->dbus_object_path, error->message);
6951 g_error_free (error);
6952 g_free (ev_window->priv->dbus_object_path);
6953 ev_window->priv->dbus_object_path = NULL;
6958 #endif /* ENABLE_DBUS */
6960 ev_window->priv->model = ev_document_model_new ();
6962 ev_window->priv->page_mode = PAGE_MODE_DOCUMENT;
6963 ev_window->priv->title = ev_window_title_new (ev_window);
6965 ev_window->priv->main_box = gtk_vbox_new (FALSE, 0);
6966 gtk_container_add (GTK_CONTAINER (ev_window), ev_window->priv->main_box);
6967 gtk_widget_show (ev_window->priv->main_box);
6969 action_group = gtk_action_group_new ("MenuActions");
6970 ev_window->priv->action_group = action_group;
6971 gtk_action_group_set_translation_domain (action_group, NULL);
6972 gtk_action_group_add_actions (action_group, entries,
6973 G_N_ELEMENTS (entries), ev_window);
6974 gtk_action_group_add_toggle_actions (action_group, toggle_entries,
6975 G_N_ELEMENTS (toggle_entries),
6977 set_action_properties (action_group);
6978 register_custom_actions (ev_window, action_group);
6980 ev_window->priv->ui_manager = gtk_ui_manager_new ();
6981 gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
6985 gtk_ui_manager_get_accel_group (ev_window->priv->ui_manager);
6986 gtk_window_add_accel_group (GTK_WINDOW (ev_window), accel_group);
6988 ev_window_set_view_accels_sensitivity (ev_window, FALSE);
6990 action_group = gtk_action_group_new ("ViewPopupActions");
6991 ev_window->priv->view_popup_action_group = action_group;
6992 gtk_action_group_set_translation_domain (action_group, NULL);
6993 gtk_action_group_add_actions (action_group, view_popup_entries,
6994 G_N_ELEMENTS (view_popup_entries),
6996 gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
6999 action_group = gtk_action_group_new ("AttachmentPopupActions");
7000 ev_window->priv->attachment_popup_action_group = action_group;
7001 gtk_action_group_set_translation_domain (action_group, NULL);
7002 gtk_action_group_add_actions (action_group, attachment_popup_entries,
7003 G_N_ELEMENTS (attachment_popup_entries),
7005 gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager,
7008 ui_path = g_build_filename (ev_application_get_data_dir (EV_APP),
7009 "evince-ui.xml", NULL);
7010 if (!gtk_ui_manager_add_ui_from_file (
7011 ev_window->priv->ui_manager, ui_path, &error))
7013 g_warning ("building menus failed: %s", error->message);
7014 g_error_free (error);
7018 ev_window->priv->recent_manager = gtk_recent_manager_get_default ();
7019 ev_window->priv->recent_action_group = NULL;
7020 ev_window->priv->recent_ui_id = 0;
7021 g_signal_connect_swapped (ev_window->priv->recent_manager,
7023 G_CALLBACK (ev_window_setup_recent),
7026 ev_window->priv->menubar =
7027 gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
7029 gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box),
7030 ev_window->priv->menubar,
7032 menuitem = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
7033 "/MainMenu/EditMenu/EditRotateLeftMenu");
7034 gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
7035 menuitem = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
7036 "/MainMenu/EditMenu/EditRotateRightMenu");
7037 gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
7039 toolbars_model = get_toolbars_model ();
7040 ev_window->priv->toolbar = GTK_WIDGET
7041 (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR,
7042 "ui-manager", ev_window->priv->ui_manager,
7043 "popup-path", "/ToolbarPopup",
7044 "model", toolbars_model,
7046 g_object_unref (toolbars_model);
7048 egg_editable_toolbar_show (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar),
7050 gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box),
7051 ev_window->priv->toolbar,
7053 gtk_widget_show (ev_window->priv->toolbar);
7055 /* Add the main area */
7056 ev_window->priv->hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
7057 g_signal_connect (ev_window->priv->hpaned,
7059 G_CALLBACK (ev_window_sidebar_position_change_cb),
7062 gtk_paned_set_position (GTK_PANED (ev_window->priv->hpaned), SIDEBAR_DEFAULT_SIZE);
7063 gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box), ev_window->priv->hpaned,
7065 gtk_widget_show (ev_window->priv->hpaned);
7067 ev_window->priv->sidebar = ev_sidebar_new ();
7068 ev_sidebar_set_model (EV_SIDEBAR (ev_window->priv->sidebar),
7069 ev_window->priv->model);
7070 gtk_paned_pack1 (GTK_PANED (ev_window->priv->hpaned),
7071 ev_window->priv->sidebar, FALSE, FALSE);
7072 gtk_widget_show (ev_window->priv->sidebar);
7074 /* Stub sidebar, for now */
7076 sidebar_widget = ev_sidebar_thumbnails_new ();
7077 ev_window->priv->sidebar_thumbs = sidebar_widget;
7078 g_signal_connect (sidebar_widget,
7079 "notify::main-widget",
7080 G_CALLBACK (sidebar_page_main_widget_update_cb),
7082 sidebar_page_main_widget_update_cb (G_OBJECT (sidebar_widget), NULL, ev_window);
7083 gtk_widget_show (sidebar_widget);
7084 ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
7087 sidebar_widget = ev_sidebar_links_new ();
7088 ev_window->priv->sidebar_links = sidebar_widget;
7089 g_signal_connect (sidebar_widget,
7091 G_CALLBACK (sidebar_widget_model_set),
7093 g_signal_connect (sidebar_widget,
7095 G_CALLBACK (sidebar_links_link_activated_cb),
7097 sidebar_page_main_widget_update_cb (G_OBJECT (sidebar_widget), NULL, ev_window);
7098 gtk_widget_show (sidebar_widget);
7099 ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
7102 sidebar_widget = ev_sidebar_attachments_new ();
7103 ev_window->priv->sidebar_attachments = sidebar_widget;
7104 g_signal_connect_object (sidebar_widget,
7106 G_CALLBACK (attachment_bar_menu_popup_cb),
7108 gtk_widget_show (sidebar_widget);
7109 ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
7112 sidebar_widget = ev_sidebar_layers_new ();
7113 ev_window->priv->sidebar_layers = sidebar_widget;
7114 g_signal_connect (sidebar_widget,
7115 "layers_visibility_changed",
7116 G_CALLBACK (sidebar_layers_visibility_changed),
7118 gtk_widget_show (sidebar_widget);
7119 ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
7122 sidebar_widget = ev_sidebar_annotations_new ();
7123 ev_window->priv->sidebar_annots = sidebar_widget;
7124 g_signal_connect (sidebar_widget,
7126 G_CALLBACK (sidebar_annots_annot_activated_cb),
7128 g_signal_connect (sidebar_widget,
7130 G_CALLBACK (sidebar_annots_begin_annot_add),
7132 g_signal_connect (sidebar_widget,
7133 "annot_add_cancelled",
7134 G_CALLBACK (sidebar_annots_annot_add_cancelled),
7136 gtk_widget_show (sidebar_widget);
7137 ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
7140 ev_window->priv->view_box = gtk_vbox_new (FALSE, 0);
7141 ev_window->priv->scrolled_window =
7142 GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW,
7143 "shadow-type", GTK_SHADOW_IN,
7145 gtk_box_pack_start (GTK_BOX (ev_window->priv->view_box),
7146 ev_window->priv->scrolled_window,
7148 gtk_widget_show (ev_window->priv->scrolled_window);
7150 gtk_paned_add2 (GTK_PANED (ev_window->priv->hpaned),
7151 ev_window->priv->view_box);
7152 gtk_widget_show (ev_window->priv->view_box);
7154 ev_window->priv->view = ev_view_new ();
7155 ev_view_set_page_cache_size (EV_VIEW (ev_window->priv->view), PAGE_CACHE_SIZE);
7156 ev_view_set_model (EV_VIEW (ev_window->priv->view), ev_window->priv->model);
7158 ev_window->priv->password_view = ev_password_view_new (GTK_WINDOW (ev_window));
7159 g_signal_connect_swapped (ev_window->priv->password_view,
7161 G_CALLBACK (ev_window_password_view_unlock),
7163 g_signal_connect_object (ev_window->priv->view, "focus_in_event",
7164 G_CALLBACK (view_actions_focus_in_cb),
7166 g_signal_connect_object (ev_window->priv->view, "focus_out_event",
7167 G_CALLBACK (view_actions_focus_out_cb),
7169 g_signal_connect_object (ev_window->priv->view, "external-link",
7170 G_CALLBACK (view_external_link_cb),
7172 g_signal_connect_object (ev_window->priv->view, "handle-link",
7173 G_CALLBACK (view_handle_link_cb),
7175 g_signal_connect_object (ev_window->priv->view, "popup",
7176 G_CALLBACK (view_menu_popup_cb),
7178 g_signal_connect_object (ev_window->priv->view, "selection-changed",
7179 G_CALLBACK (view_selection_changed_cb),
7181 g_signal_connect_object (ev_window->priv->view, "annot-added",
7182 G_CALLBACK (view_annot_added),
7184 g_signal_connect_object (ev_window->priv->view, "layers-changed",
7185 G_CALLBACK (view_layers_changed_cb),
7188 g_signal_connect_swapped (ev_window->priv->view, "sync-source",
7189 G_CALLBACK (ev_window_sync_source),
7192 gtk_widget_show (ev_window->priv->view);
7193 gtk_widget_show (ev_window->priv->password_view);
7196 ev_window->priv->find_bar = egg_find_bar_new ();
7197 gtk_box_pack_end (GTK_BOX (ev_window->priv->main_box),
7198 ev_window->priv->find_bar,
7201 /* We own a ref on these widgets, as we can swap them in and out */
7202 g_object_ref (ev_window->priv->view);
7203 g_object_ref (ev_window->priv->password_view);
7205 gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window),
7206 ev_window->priv->view);
7208 /* Connect to model signals */
7209 g_signal_connect_swapped (ev_window->priv->model,
7211 G_CALLBACK (ev_window_page_changed_cb),
7213 g_signal_connect (ev_window->priv->model,
7215 G_CALLBACK (ev_window_document_changed_cb),
7217 g_signal_connect (ev_window->priv->model,
7219 G_CALLBACK (ev_window_zoom_changed_cb),
7221 g_signal_connect (ev_window->priv->model,
7222 "notify::sizing-mode",
7223 G_CALLBACK (ev_window_sizing_mode_changed_cb),
7225 g_signal_connect (ev_window->priv->model,
7227 G_CALLBACK (ev_window_rotation_changed_cb),
7229 g_signal_connect (ev_window->priv->model,
7230 "notify::continuous",
7231 G_CALLBACK (ev_window_continuous_changed_cb),
7233 g_signal_connect (ev_window->priv->model,
7234 "notify::dual-page",
7235 G_CALLBACK (ev_window_dual_mode_changed_cb),
7237 g_signal_connect (ev_window->priv->model,
7238 "notify::inverted-colors",
7239 G_CALLBACK (ev_window_inverted_colors_changed_cb),
7242 /* Connect sidebar signals */
7243 g_signal_connect (ev_window->priv->sidebar,
7245 G_CALLBACK (ev_window_sidebar_visibility_changed_cb),
7247 g_signal_connect (ev_window->priv->sidebar,
7248 "notify::current-page",
7249 G_CALLBACK (ev_window_sidebar_current_page_changed_cb),
7252 /* Connect to find bar signals */
7253 g_signal_connect (ev_window->priv->find_bar,
7255 G_CALLBACK (find_bar_previous_cb),
7257 g_signal_connect (ev_window->priv->find_bar,
7259 G_CALLBACK (find_bar_next_cb),
7261 g_signal_connect (ev_window->priv->find_bar,
7263 G_CALLBACK (find_bar_close_cb),
7265 g_signal_connect (ev_window->priv->find_bar,
7266 "notify::search-string",
7267 G_CALLBACK (find_bar_search_changed_cb),
7269 g_signal_connect (ev_window->priv->find_bar,
7270 "notify::case-sensitive",
7271 G_CALLBACK (find_bar_search_changed_cb),
7273 g_signal_connect (ev_window->priv->find_bar,
7275 G_CALLBACK (find_bar_visibility_changed_cb),
7277 g_signal_connect (ev_window->priv->find_bar,
7279 G_CALLBACK (find_bar_scroll),
7283 ev_window->priv->view_popup = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
7285 ev_window->priv->link = NULL;
7287 ev_window->priv->attachment_popup = gtk_ui_manager_get_widget (ev_window->priv->ui_manager,
7288 "/AttachmentPopup");
7289 ev_window->priv->attach_list = NULL;
7291 /* Media player keys */
7292 mpkeys = ev_application_get_media_keys (EV_APP);
7294 g_signal_connect_swapped (mpkeys, "key_pressed",
7295 G_CALLBACK (ev_window_media_player_key_pressed),
7299 /* Give focus to the document view */
7300 gtk_widget_grab_focus (ev_window->priv->view);
7302 ev_window->priv->default_settings = g_settings_new (GS_SCHEMA_NAME".Default");
7303 g_settings_delay (ev_window->priv->default_settings);
7305 /* Set it user interface params */
7306 ev_window_setup_recent (ev_window);
7308 ev_window_setup_gtk_settings (ev_window);
7310 setup_chrome_from_metadata (ev_window);
7311 update_chrome_actions (ev_window);
7312 update_chrome_visibility (ev_window);
7314 gtk_window_set_default_size (GTK_WINDOW (ev_window), 600, 600);
7316 setup_view_from_metadata (ev_window);
7317 setup_sidebar_from_metadata (ev_window);
7319 ev_window_sizing_mode_changed_cb (ev_window->priv->model, NULL, ev_window);
7320 ev_window_setup_action_sensitivity (ev_window);
7323 gtk_drag_dest_set (GTK_WIDGET (ev_window),
7324 GTK_DEST_DEFAULT_ALL,
7327 gtk_drag_dest_add_uri_targets (GTK_WIDGET (ev_window));
7333 * Creates a #GtkWidget that represents the window.
7335 * Returns: the #GtkWidget that represents the window.
7338 ev_window_new (void)
7340 GtkWidget *ev_window;
7342 ev_window = GTK_WIDGET (g_object_new (EV_TYPE_WINDOW,
7343 "type", GTK_WINDOW_TOPLEVEL,
7350 ev_window_get_dbus_object_path (EvWindow *ev_window)
7353 return ev_window->priv->dbus_object_path;