X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-window.c;h=b7c4bd2dd25ed48eba67cc788c0877487172c5d1;hb=a2b36d8928c30f93f74869b294e72d2484422646;hp=b6404493e0a0216fc450d4b1f86d95ba08ef8f21;hpb=4d90dbf2c9bf88b4cc664134d9e3f2e15365ed4e;p=evince.git diff --git a/shell/ev-window.c b/shell/ev-window.c index b6404493..b7c4bd2d 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ /* this file is part of evince, a gnome document viewer * + * Copyright (C) 2009 Juanjo Marín * Copyright (C) 2008 Carlos Garcia Campos * Copyright (C) 2004 Martin Kretzschmar * Copyright (C) 2004 Red Hat, Inc. @@ -22,7 +23,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H @@ -33,16 +34,13 @@ #include #include #include +#include #include #include #include #include -#ifdef WITH_GCONF -#include -#endif - #include "egg-editable-toolbar.h" #include "egg-toolbar-editor.h" #include "egg-toolbars-model.h" @@ -58,8 +56,9 @@ #include "ev-document-fonts.h" #include "ev-document-images.h" #include "ev-document-links.h" -#include "ev-document-thumbnails.h" +#include "ev-document-annotations.h" #include "ev-document-type-builtins.h" +#include "ev-document-misc.h" #include "ev-file-exporter.h" #include "ev-file-helpers.h" #include "ev-file-monitor.h" @@ -68,12 +67,13 @@ #include "ev-job-scheduler.h" #include "ev-jobs.h" #include "ev-message-area.h" -#include "ev-metadata-manager.h" +#include "ev-metadata.h" #include "ev-navigation-action.h" #include "ev-open-recent-action.h" #include "ev-page-action.h" #include "ev-password-view.h" #include "ev-properties-dialog.h" +#include "ev-sidebar-annotations.h" #include "ev-sidebar-attachments.h" #include "ev-sidebar.h" #include "ev-sidebar-links.h" @@ -84,20 +84,18 @@ #include "ev-utils.h" #include "ev-keyring.h" #include "ev-view.h" +#include "ev-view-presentation.h" #include "ev-view-type-builtins.h" #include "ev-window.h" #include "ev-window-title.h" #include "ev-print-operation.h" #include "ev-progress-message-area.h" +#include "ev-annotation-properties-dialog.h" #ifdef ENABLE_DBUS #include "ev-media-player-keys.h" #endif /* ENABLE_DBUS */ -#ifdef ENABLE_PDF -#include -#endif - typedef enum { PAGE_MODE_DOCUMENT, PAGE_MODE_PASSWORD @@ -132,12 +130,19 @@ struct _EvWindowPrivate { GtkWidget *find_bar; GtkWidget *scrolled_window; GtkWidget *view; + GtkWidget *presentation_view; GtkWidget *message_area; GtkWidget *password_view; GtkWidget *sidebar_thumbs; GtkWidget *sidebar_links; GtkWidget *sidebar_attachments; GtkWidget *sidebar_layers; + GtkWidget *sidebar_annots; + + /* Settings */ + GSettings *settings; + GSettings *default_settings; + GSettings *lockdown_settings; /* Menubar accels */ guint menubar_accel_keyval; @@ -163,13 +168,11 @@ struct _EvWindowPrivate { /* Fullscreen mode */ GtkWidget *fullscreen_toolbar; - /* Presentation mode */ - guint presentation_timeout_id; - /* Popup view */ - GtkWidget *view_popup; - EvLink *link; - EvImage *image; + GtkWidget *view_popup; + EvLink *link; + EvImage *image; + EvAnnotation *annot; /* Popup attachment */ GtkWidget *attachment_popup; @@ -188,6 +191,8 @@ struct _EvWindowPrivate { EvHistory *history; EvWindowPageMode page_mode; EvWindowTitle *title; + EvMetadata *metadata; + gboolean is_new_doc; /* Load params */ EvLinkDest *dest; @@ -205,29 +210,53 @@ struct _EvWindowPrivate { GtkPrintSettings *print_settings; GtkPageSetup *print_page_setup; gboolean close_after_print; + +#ifdef ENABLE_DBUS + /* DBus */ + guint dbus_object_id; + gchar *dbus_object_path; +#endif }; #define EV_WINDOW_GET_PRIVATE(object) \ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_WINDOW, EvWindowPrivate)) +#define EV_WINDOW_IS_PRESENTATION(w) (w->priv->presentation_view != NULL) + #define PAGE_SELECTOR_ACTION "PageSelector" #define ZOOM_CONTROL_ACTION "ViewZoom" #define NAVIGATION_ACTION "Navigation" -#define GCONF_OVERRIDE_RESTRICTIONS "/apps/evince/override_restrictions" -#define GCONF_LOCKDOWN_SAVE "/desktop/gnome/lockdown/disable_save_to_disk" -#define GCONF_LOCKDOWN_PRINT "/desktop/gnome/lockdown/disable_printing" +#define GS_LOCKDOWN_SCHEMA_NAME "org.gnome.desktop.lockdown" +#define GS_LOCKDOWN_SAVE "disable-save-to-disk" +#define GS_LOCKDOWN_PRINT "disable-printing" +#define GS_LOCKDOWN_PRINT_SETUP "disable-print-setup" + +#ifdef ENABLE_DBUS +#define EV_WINDOW_DBUS_OBJECT_PATH "/org/gnome/evince/Window/%d" +#define EV_WINDOW_DBUS_INTERFACE "org.gnome.evince.Window" +#endif -#define PRESENTATION_TIMEOUT 5 +#define GS_SCHEMA_NAME "org.gnome.Evince" +#define GS_OVERRIDE_RESTRICTIONS "override-restrictions" #define SIDEBAR_DEFAULT_SIZE 132 #define LINKS_SIDEBAR_ID "links" #define THUMBNAILS_SIDEBAR_ID "thumbnails" #define ATTACHMENTS_SIDEBAR_ID "attachments" #define LAYERS_SIDEBAR_ID "layers" +#define ANNOTS_SIDEBAR_ID "annotations" + +#define EV_PRINT_SETTINGS_FILE "print-settings" +#define EV_PRINT_SETTINGS_GROUP "Print Settings" +#define EV_PAGE_SETUP_GROUP "Page Setup" + +#define EV_TOOLBARS_FILENAME "evince-toolbar.xml" #define MIN_SCALE 0.05409 -#define MAX_SCALE 4.0 +#define PAGE_CACHE_SIZE 52428800 /* 50MB */ + +#define MAX_RECENT_ITEM_LEN (40) static const gchar *document_print_settings[] = { GTK_PRINT_SETTINGS_N_COPIES, @@ -245,6 +274,8 @@ static void ev_window_update_actions (EvWindow *ev_window); static void ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar, GParamSpec *pspec, EvWindow *ev_window); +static void ev_window_view_toolbar_cb (GtkAction *action, + EvWindow *ev_window); static void ev_window_set_page_mode (EvWindow *window, EvWindowPageMode page_mode); static void ev_window_load_job_cb (EvJob *job, @@ -285,6 +316,8 @@ static void ev_view_popup_cmd_save_image_as (GtkAction *actio EvWindow *window); static void ev_view_popup_cmd_copy_image (GtkAction *action, EvWindow *window); +static void ev_view_popup_cmd_annot_properties (GtkAction *action, + EvWindow *window); static void ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window); static void ev_attachment_popup_cmd_save_attachment_as (GtkAction *action, @@ -307,10 +340,25 @@ static void ev_window_load_file_remote (EvWindow *ev_wi static void ev_window_media_player_key_pressed (EvWindow *window, const gchar *key, gpointer user_data); -static void ev_window_save_print_page_setup (EvWindow *window); +static void ev_window_update_max_min_scale (EvWindow *window); +#ifdef ENABLE_DBUS +static void ev_window_emit_closed (EvWindow *window); +static void ev_window_emit_doc_loaded (EvWindow *window); +#endif + +static guint ev_window_n_copies = 0; G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW) +static gdouble +get_screen_dpi (EvWindow *window) +{ + GdkScreen *screen; + + screen = gtk_window_get_screen (GTK_WINDOW (window)); + return ev_document_misc_get_screen_dpi (screen); +} + static void ev_window_set_action_sensitive (EvWindow *ev_window, const char *name, @@ -327,7 +375,6 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) { EvDocument *document = ev_window->priv->document; const EvDocumentInfo *info = NULL; - gboolean has_document = FALSE; gboolean ok_to_print = TRUE; gboolean ok_to_copy = TRUE; @@ -336,9 +383,6 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) gboolean can_get_text = FALSE; gboolean has_pages = FALSE; gboolean can_find = FALSE; -#ifdef WITH_GCONF - GConfClient *client; -#endif if (document) { has_document = TRUE; @@ -358,12 +402,12 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) can_find = TRUE; } -#ifdef WITH_GCONF - client = gconf_client_get_default (); - override_restrictions = gconf_client_get_bool (client, - GCONF_OVERRIDE_RESTRICTIONS, - NULL); -#endif + if (has_document && ev_window->priv->settings) { + override_restrictions = + g_settings_get_boolean (ev_window->priv->settings, + GS_OVERRIDE_RESTRICTIONS); + } + if (!override_restrictions && info && info->fields_mask & EV_DOCUMENT_INFO_PERMISSIONS) { ok_to_print = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_PRINT); ok_to_copy = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_COPY); @@ -372,22 +416,19 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) if (has_document && !ev_print_operation_exists_for_document(document)) ok_to_print = FALSE; -#ifdef WITH_GCONF - if (gconf_client_get_bool (client, GCONF_LOCKDOWN_SAVE, NULL)) { + if (has_document && ev_window->priv->lockdown_settings && + g_settings_get_boolean (ev_window->priv->lockdown_settings, GS_LOCKDOWN_SAVE)) { ok_to_copy = FALSE; } - if (gconf_client_get_bool (client, GCONF_LOCKDOWN_PRINT, NULL)) { + if (has_document && ev_window->priv->lockdown_settings && + g_settings_get_boolean (ev_window->priv->lockdown_settings, GS_LOCKDOWN_PRINT)) { ok_to_print = FALSE; } - g_object_unref (client); -#endif - /* File menu */ ev_window_set_action_sensitive (ev_window, "FileOpenCopy", has_document); ev_window_set_action_sensitive (ev_window, "FileSaveAs", has_document && ok_to_copy); - ev_window_set_action_sensitive (ev_window, "FilePageSetup", has_pages && ok_to_print); ev_window_set_action_sensitive (ev_window, "FilePrint", has_pages && ok_to_print); ev_window_set_action_sensitive (ev_window, "FileProperties", has_document && has_properties); @@ -405,6 +446,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "ViewPageWidth", has_pages); ev_window_set_action_sensitive (ev_window, "ViewReload", has_pages); ev_window_set_action_sensitive (ev_window, "ViewAutoscroll", has_pages); + ev_window_set_action_sensitive (ev_window, "ViewInvertedColors", has_pages); /* Toolbar-specific actions: */ ev_window_set_action_sensitive (ev_window, PAGE_SELECTOR_ACTION, has_pages); @@ -443,7 +485,7 @@ ev_window_update_actions (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "F3", has_pages && can_find_in_page); - presentation_mode = ev_view_get_presentation (view); + presentation_mode = EV_WINDOW_IS_PRESENTATION (ev_window); ev_window_set_action_sensitive (ev_window, "ViewZoomIn", has_pages && @@ -477,7 +519,7 @@ ev_window_update_actions (EvWindow *ev_window) ZOOM_CONTROL_ACTION); real_zoom = ev_document_model_get_scale (ev_window->priv->model); - real_zoom *= 72.0 / get_screen_dpi (GTK_WINDOW (ev_window)); + real_zoom *= 72.0 / get_screen_dpi (ev_window); zoom = ephy_zoom_get_nearest_zoom_level (real_zoom); ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action), zoom); @@ -506,6 +548,8 @@ ev_window_set_view_accels_sensitivity (EvWindow *window, gboolean sensitive) ev_window_set_action_sensitive (window, "KpPlus", sensitive); ev_window_set_action_sensitive (window, "KpMinus", sensitive); ev_window_set_action_sensitive (window, "Equal", sensitive); + ev_window_set_action_sensitive (window, "p", sensitive); + ev_window_set_action_sensitive (window, "n", sensitive); ev_window_set_action_sensitive (window, "Slash", sensitive && can_find); } @@ -529,8 +573,8 @@ update_chrome_visibility (EvWindow *window) gboolean menubar, toolbar, findbar, fullscreen_toolbar, sidebar; gboolean fullscreen_mode, presentation, fullscreen; - presentation = ev_view_get_presentation (EV_VIEW (priv->view)); - fullscreen = ev_view_get_fullscreen (EV_VIEW (priv->view)); + presentation = EV_WINDOW_IS_PRESENTATION (window); + fullscreen = ev_document_model_get_fullscreen (priv->model); fullscreen_mode = fullscreen || presentation; menubar = (priv->chrome & EV_CHROME_MENUBAR) != 0 && !fullscreen_mode; @@ -539,7 +583,7 @@ update_chrome_visibility (EvWindow *window) fullscreen_toolbar = ((priv->chrome & EV_CHROME_FULLSCREEN_TOOLBAR) != 0 || (priv->chrome & EV_CHROME_RAISE_TOOLBAR) != 0) && fullscreen; findbar = (priv->chrome & EV_CHROME_FINDBAR) != 0; - sidebar = (priv->chrome & EV_CHROME_SIDEBAR) != 0 && !presentation; + sidebar = (priv->chrome & EV_CHROME_SIDEBAR) != 0 && priv->document && !presentation; set_widget_visibility (priv->menubar, menubar); set_widget_visibility (priv->toolbar, toolbar); @@ -571,16 +615,8 @@ update_sizing_buttons (EvWindow *window) GtkActionGroup *action_group = window->priv->action_group; GtkAction *action; gboolean best_fit, page_width; - EvSizingMode sizing_mode; - - if (window->priv->view == NULL) - return; - - g_object_get (window->priv->view, - "sizing_mode", &sizing_mode, - NULL); - switch (sizing_mode) { + switch (ev_document_model_get_sizing_mode (window->priv->model)) { case EV_SIZING_BEST_FIT: best_fit = TRUE; page_width = FALSE; @@ -619,6 +655,22 @@ update_sizing_buttons (EvWindow *window) } } +static void +update_chrome_actions (EvWindow *window) +{ + EvWindowPrivate *priv = window->priv; + GtkActionGroup *action_group = priv->action_group; + GtkAction *action; + + action= gtk_action_group_get_action (action_group, "ViewToolbar"); + g_signal_handlers_block_by_func + (action, G_CALLBACK (ev_window_view_toolbar_cb), window); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), + (priv->chrome & EV_CHROME_TOOLBAR) != 0); + g_signal_handlers_unblock_by_func + (action, G_CALLBACK (ev_window_view_toolbar_cb), window); +} + /** * ev_window_is_empty: * @ev_window: The instance of the #EvWindow. @@ -784,8 +836,7 @@ ev_window_add_history (EvWindow *window, gint page, EvLink *link) if (link) { action = g_object_ref (ev_link_get_action (link)); dest = ev_link_action_get_dest (action); - page = ev_link_dest_get_page (dest); - page_label = ev_view_page_label_from_dest (EV_VIEW (window->priv->view), dest); + page_label = ev_document_links_get_dest_page_label (EV_DOCUMENT_LINKS (window->priv->document), dest); } else { dest = ev_link_dest_new_page (page); action = ev_link_action_new_dest (dest); @@ -813,7 +864,7 @@ ev_window_add_history (EvWindow *window, gint page, EvLink *link) } if (find_task.chapter) - link_title = g_strdup_printf (_("Page %s - %s"), page_label, find_task.chapter); + link_title = g_strdup_printf (_("Page %s — %s"), page_label, find_task.chapter); else link_title = g_strdup_printf (_("Page %s"), page_label); @@ -836,6 +887,21 @@ view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window) ev_window_add_history (window, current_page, NULL); } +static void +view_selection_changed_cb (EvView *view, + EvWindow *window) +{ + ev_window_set_action_sensitive (window, "EditCopy", + ev_view_get_has_selection (view)); +} + +static void +view_layers_changed_cb (EvView *view, + EvWindow *window) +{ + ev_sidebar_layers_update_layers_state (EV_SIDEBAR_LAYERS (window->priv->sidebar_layers)); +} + static void ev_window_page_changed_cb (EvWindow *ev_window, gint old_page, @@ -851,8 +917,67 @@ ev_window_page_changed_cb (EvWindow *ev_window, ev_window_add_history (ev_window, old_page, NULL); } - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_int (ev_window->priv->uri, "page", new_page); + if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) + ev_metadata_set_int (ev_window->priv->metadata, "page", new_page); +} + +static const gchar * +ev_window_sidebar_get_current_page_id (EvWindow *ev_window) +{ + GtkWidget *current_page; + const gchar *id; + + g_object_get (ev_window->priv->sidebar, + "current_page", ¤t_page, + NULL); + + if (current_page == ev_window->priv->sidebar_links) { + id = LINKS_SIDEBAR_ID; + } else if (current_page == ev_window->priv->sidebar_thumbs) { + id = THUMBNAILS_SIDEBAR_ID; + } else if (current_page == ev_window->priv->sidebar_attachments) { + id = ATTACHMENTS_SIDEBAR_ID; + } else if (current_page == ev_window->priv->sidebar_layers) { + id = LAYERS_SIDEBAR_ID; + } else if (current_page == ev_window->priv->sidebar_annots) { + id = ANNOTS_SIDEBAR_ID; + } else { + g_assert_not_reached(); + } + + g_object_unref (current_page); + + return id; +} + +static void +ev_window_sidebar_set_current_page (EvWindow *window, + const gchar *page_id) +{ + EvDocument *document = window->priv->document; + EvSidebar *sidebar = EV_SIDEBAR (window->priv->sidebar); + GtkWidget *links = window->priv->sidebar_links; + GtkWidget *thumbs = window->priv->sidebar_thumbs; + GtkWidget *attachments = window->priv->sidebar_attachments; + GtkWidget *annots = window->priv->sidebar_annots; + GtkWidget *layers = window->priv->sidebar_layers; + + if (strcmp (page_id, LINKS_SIDEBAR_ID) == 0 && + ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) { + ev_sidebar_set_page (sidebar, links); + } else if (strcmp (page_id, THUMBNAILS_SIDEBAR_ID) == 0 && + ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) { + ev_sidebar_set_page (sidebar, thumbs); + } else if (strcmp (page_id, ATTACHMENTS_SIDEBAR_ID) == 0 && + ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) { + ev_sidebar_set_page (sidebar, attachments); + } else if (strcmp (page_id, LAYERS_SIDEBAR_ID) == 0 && + ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (layers), document)) { + ev_sidebar_set_page (sidebar, layers); + } else if (strcmp (page_id, ANNOTS_SIDEBAR_ID) == 0 && + ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (annots), document)) { + ev_sidebar_set_page (sidebar, annots); + } } static void @@ -870,162 +995,217 @@ static void setup_chrome_from_metadata (EvWindow *window) { EvChrome chrome = EV_CHROME_NORMAL; - GValue show_toolbar = { 0, }; + gboolean show_toolbar = TRUE; + + if (ev_window_is_empty (window)) { + window->priv->chrome = chrome; + + return; + } - if (ev_metadata_manager_get (NULL, "show_toolbar", &show_toolbar, FALSE)) { - if (!g_value_get_boolean (&show_toolbar)) - chrome &= ~EV_CHROME_TOOLBAR; - g_value_unset (&show_toolbar); + if (!window->priv->metadata) { + show_toolbar = g_settings_get_boolean (window->priv->default_settings, "show-toolbar"); + } else if (!ev_metadata_get_boolean (window->priv->metadata, "show_toolbar", &show_toolbar)) { + if (window->priv->is_new_doc) + show_toolbar = g_settings_get_boolean (window->priv->default_settings, "show-toolbar"); } + + if (!show_toolbar) + chrome &= ~EV_CHROME_TOOLBAR; + window->priv->chrome = chrome; } static void setup_sidebar_from_metadata (EvWindow *window) { - gchar *uri = window->priv->uri; EvDocument *document = window->priv->document; - GtkWidget *sidebar = window->priv->sidebar; - GtkWidget *links = window->priv->sidebar_links; - GtkWidget *thumbs = window->priv->sidebar_thumbs; - GtkWidget *attachments = window->priv->sidebar_attachments; - GtkWidget *layers = window->priv->sidebar_layers; - GValue sidebar_size = { 0, }; - GValue sidebar_page = { 0, }; - GValue sidebar_visibility = { 0, }; + GSettings *settings = window->priv->default_settings; + gchar *page_id; + gint sidebar_size; + gboolean sidebar_visibility = TRUE; - if (ev_metadata_manager_get (uri, "sidebar_size", &sidebar_size, FALSE)) { - gtk_paned_set_position (GTK_PANED (window->priv->hpaned), - g_value_get_int (&sidebar_size)); - g_value_unset(&sidebar_size); + if (ev_window_is_empty (window)) + return; + + if (!window->priv->metadata) { + sidebar_visibility = g_settings_get_boolean (settings, "show-sidebar"); + } else if (!ev_metadata_get_boolean (window->priv->metadata, "sidebar_visibility", &sidebar_visibility)) { + if (window->priv->is_new_doc) + sidebar_visibility = g_settings_get_boolean (settings, "show-sidebar"); } - - if (document && ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page, TRUE)) { - const char *page_id = g_value_get_string (&sidebar_page); - - if (strcmp (page_id, LINKS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) { - ev_sidebar_set_page (EV_SIDEBAR (sidebar), links); - } else if (strcmp (page_id, THUMBNAILS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) { - ev_sidebar_set_page (EV_SIDEBAR (sidebar), thumbs); - } else if (strcmp (page_id, ATTACHMENTS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) { - ev_sidebar_set_page (EV_SIDEBAR (sidebar), attachments); - } else if (strcmp (page_id, LAYERS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (layers), document)) { - ev_sidebar_set_page (EV_SIDEBAR (sidebar), layers); - } - g_value_unset (&sidebar_page); - } else if (document) { - if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) { - ev_sidebar_set_page (EV_SIDEBAR (sidebar), links); - } else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) { - ev_sidebar_set_page (EV_SIDEBAR (sidebar), thumbs); - } else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) { - ev_sidebar_set_page (EV_SIDEBAR (sidebar), attachments); - } else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (layers), document)) { - ev_sidebar_set_page (EV_SIDEBAR (sidebar), layers); + + update_chrome_flag (window, EV_CHROME_SIDEBAR, sidebar_visibility); + update_chrome_visibility (window); + + if (!window->priv->metadata) { + /* Set default values */ + gtk_paned_set_position (GTK_PANED (window->priv->hpaned), + g_settings_get_int (settings, "sidebar-size")); + if (document) { + page_id = g_settings_get_string (settings, "sidebar-page"); + ev_window_sidebar_set_current_page (window, page_id); + g_free (page_id); } + + return; } - if (ev_metadata_manager_get (uri, "sidebar_visibility", &sidebar_visibility, FALSE)) { - update_chrome_flag (window, EV_CHROME_SIDEBAR, g_value_get_boolean (&sidebar_visibility)); - g_value_unset (&sidebar_visibility); - update_chrome_visibility (window); + if (ev_metadata_get_int (window->priv->metadata, "sidebar_size", &sidebar_size)) { + gtk_paned_set_position (GTK_PANED (window->priv->hpaned), sidebar_size); + } else if (window->priv->is_new_doc) { + gtk_paned_set_position (GTK_PANED (window->priv->hpaned), + g_settings_get_int (settings, "sidebar-size")); + } + + if (!document) + return; + + if (ev_metadata_get_string (window->priv->metadata, "sidebar_page", &page_id)) { + ev_window_sidebar_set_current_page (window, page_id); + } else if (window->priv->is_new_doc) { + page_id = g_settings_get_string (settings, "sidebar-page"); + ev_window_sidebar_set_current_page (window, page_id); + g_free (page_id); } } static void setup_model_from_metadata (EvWindow *window) { - gchar *uri = window->priv->uri; - GValue page = { 0, }; - GValue sizing_mode = { 0, }; - GValue zoom = { 0, }; - GValue rotation = { 0, }; + GSettings *settings = window->priv->default_settings; + gint page; + gchar *sizing_mode; + gdouble zoom; + gint rotation; + gboolean inverted_colors = FALSE; + gboolean continuous = FALSE; + gboolean dual_page = FALSE; + gboolean fullscreen = FALSE; + + if (!window->priv->metadata) { + /* Set default values */ + ev_document_model_set_sizing_mode (window->priv->model, + g_settings_get_enum (settings, "sizing-mode")); + ev_document_model_set_inverted_colors (window->priv->model, + g_settings_get_boolean (settings, "inverted-colors")); + ev_document_model_set_continuous (window->priv->model, + g_settings_get_boolean (settings, "continuous")); + ev_document_model_set_dual_page (window->priv->model, + g_settings_get_boolean (settings, "dual-page")); + fullscreen = g_settings_get_boolean (settings, "fullscreen"); + if (fullscreen) + ev_window_run_fullscreen (window); + + return; + } /* Current page */ - if (ev_metadata_manager_get (uri, "page", &page, TRUE)) { - ev_document_model_set_page (window->priv->model, - g_value_get_int (&page)); - g_value_unset (&page); + if (!window->priv->dest && + ev_metadata_get_int (window->priv->metadata, "page", &page)) { + ev_document_model_set_page (window->priv->model, page); } /* Sizing mode */ - if (ev_metadata_manager_get (uri, "sizing_mode", &sizing_mode, FALSE)) { + if (ev_metadata_get_string (window->priv->metadata, "sizing_mode", &sizing_mode)) { GEnumValue *enum_value; enum_value = g_enum_get_value_by_nick - (g_type_class_peek (EV_TYPE_SIZING_MODE), g_value_get_string (&sizing_mode)); + (g_type_class_peek (EV_TYPE_SIZING_MODE), sizing_mode); ev_document_model_set_sizing_mode (window->priv->model, enum_value->value); - g_value_unset (&sizing_mode); + } else if (window->priv->is_new_doc) { + ev_document_model_set_sizing_mode (window->priv->model, + g_settings_get_enum (settings, "sizing-mode")); } /* Zoom */ if (ev_document_model_get_sizing_mode (window->priv->model) == EV_SIZING_FREE && - ev_metadata_manager_get (uri, "zoom", &zoom, FALSE)) { - gdouble zoom_value; - - zoom_value = g_value_get_double (&zoom); - zoom_value *= get_screen_dpi (GTK_WINDOW (window)) / 72.0; - ev_document_model_set_scale (window->priv->model, zoom_value); - g_value_unset (&zoom); + ev_metadata_get_double (window->priv->metadata, "zoom", &zoom)) { + zoom *= get_screen_dpi (window) / 72.0; + ev_document_model_set_scale (window->priv->model, zoom); } /* Rotation */ - if (ev_metadata_manager_get (uri, "rotation", &rotation, TRUE)) { - gint rotation_value; - - switch (g_value_get_int (&rotation)) { + if (ev_metadata_get_int (window->priv->metadata, "rotation", &rotation)) { + switch (rotation) { case 90: - rotation_value = 90; + rotation = 90; break; case 180: - rotation_value = 180; + rotation = 180; break; case 270: - rotation_value = 270; + rotation = 270; break; default: - rotation_value = 0; + rotation = 0; break; } - ev_document_model_set_rotation (window->priv->model, rotation_value); - g_value_unset (&rotation); + ev_document_model_set_rotation (window->priv->model, rotation); } + + /* Inverted Colors */ + if (ev_metadata_get_boolean (window->priv->metadata, "inverted-colors", &inverted_colors)) { + ev_document_model_set_inverted_colors (window->priv->model, inverted_colors); + } else if (window->priv->is_new_doc) { + ev_document_model_set_inverted_colors (window->priv->model, + g_settings_get_boolean (settings, "inverted-colors")); + } + + /* Continuous */ + if (ev_metadata_get_boolean (window->priv->metadata, "continuous", &continuous)) { + ev_document_model_set_continuous (window->priv->model, continuous); + } else if (window->priv->is_new_doc) { + ev_document_model_set_continuous (window->priv->model, + g_settings_get_boolean (settings, "continuous")); + } + + /* Dual page */ + if (ev_metadata_get_boolean (window->priv->metadata, "dual-page", &dual_page)) { + ev_document_model_set_dual_page (window->priv->model, dual_page); + } else if (window->priv->is_new_doc) { + ev_document_model_set_dual_page (window->priv->model, + g_settings_get_boolean (settings, "dual-page")); + } + + /* Fullscreen */ + if (!ev_metadata_get_boolean (window->priv->metadata, "fullscreen", &fullscreen)) { + if (window->priv->is_new_doc) + fullscreen = g_settings_get_boolean (settings, "fullscreen"); + } + + if (fullscreen) + ev_window_run_fullscreen (window); } static void setup_document_from_metadata (EvWindow *window) { - gchar *uri = window->priv->uri; - GValue page = { 0, }; - GValue width = { 0, }; - GValue height = { 0, }; - GValue width_ratio = { 0, }; - GValue height_ratio = { 0, }; - -#if 0 /* FIXME */ - /* View the previously shown page, but make sure to not open a document on - * the last page, since closing it on the last page most likely means the - * user was finished reading the document. In that case, reopening should - * show the first page. */ - if (ev_metadata_manager_get (uri, "page", &page, TRUE)) { - gint n_pages; - gint new_page; - - n_pages = ev_document_get_n_pages (window->priv->document); - new_page = CLAMP (g_value_get_int (&page), 0, n_pages - 1); - ev_document_model_set_page (window->priv->model, new_page); - g_value_unset (&page); - } -#endif + gint page, n_pages; + gint width; + gint height; + gdouble width_ratio; + gdouble height_ratio; setup_sidebar_from_metadata (window); - if (ev_metadata_manager_get (uri, "window_width", &width, TRUE) && - ev_metadata_manager_get (uri, "window_height", &height, TRUE)) - return; /* size was already set in setup_size_from_metadata */ + if (window->priv->metadata) { + /* Make sure to not open a document on the last page, + * since closing it on the last page most likely means the + * user was finished reading the document. In that case, reopening should + * show the first page. */ + page = ev_document_model_get_page (window->priv->model); + n_pages = ev_document_get_n_pages (window->priv->document); + if (page == n_pages - 1) + ev_document_model_set_page (window->priv->model, 0); + + if (ev_metadata_get_int (window->priv->metadata, "window_width", &width) && + ev_metadata_get_int (window->priv->metadata, "window_height", &height)) + return; /* size was already set in setup_size_from_metadata */ + } - if (ev_metadata_manager_get (uri, "window_width_ratio", &width_ratio, FALSE) && - ev_metadata_manager_get (uri, "window_height_ratio", &height_ratio, FALSE)) { + g_settings_get (window->priv->default_settings, "window-ratio", "(dd)", &width_ratio, &height_ratio); + if (width_ratio > 0. && height_ratio > 0.) { gdouble document_width; gdouble document_height; GdkScreen *screen; @@ -1035,101 +1215,68 @@ setup_document_from_metadata (EvWindow *window) ev_document_get_max_page_size (window->priv->document, &document_width, &document_height); - request_width = (gint)(g_value_get_double (&width_ratio) * document_width + 0.5); - request_height = (gint)(g_value_get_double (&height_ratio) * document_height + 0.5); - + request_width = (gint)(width_ratio * document_width + 0.5); + request_height = (gint)(height_ratio * document_height + 0.5); + screen = gtk_window_get_screen (GTK_WINDOW (window)); - if (screen) { request_width = MIN (request_width, gdk_screen_get_width (screen)); - request_height = MIN (request_width, gdk_screen_get_height (screen)); + request_height = MIN (request_height, gdk_screen_get_height (screen)); } - + if (request_width > 0 && request_height > 0) { gtk_window_resize (GTK_WINDOW (window), request_width, request_height); } - g_value_unset (&width_ratio); - g_value_unset (&height_ratio); } } static void setup_size_from_metadata (EvWindow *window) { - char *uri = window->priv->uri; - GValue width = { 0, }; - GValue height = { 0, }; - GValue maximized = { 0, }; - GValue x = { 0, }; - GValue y = { 0, }; + gint width; + gint height; + gboolean maximized; + gint x; + gint y; + + if (!window->priv->metadata) + return; - if (ev_metadata_manager_get (uri, "window_maximized", &maximized, FALSE)) { - if (g_value_get_boolean (&maximized)) { + if (ev_metadata_get_boolean (window->priv->metadata, "window_maximized", &maximized)) { + if (maximized) { gtk_window_maximize (GTK_WINDOW (window)); - g_value_unset (&maximized); return; } else { gtk_window_unmaximize (GTK_WINDOW (window)); } - g_value_unset (&maximized); } - if (ev_metadata_manager_get (uri, "window_x", &x, TRUE) && - ev_metadata_manager_get (uri, "window_y", &y, TRUE)) { - gtk_window_move (GTK_WINDOW (window), g_value_get_int (&x), - g_value_get_int (&y)); - g_value_unset (&x); - g_value_unset (&y); + if (ev_metadata_get_int (window->priv->metadata, "window_x", &x) && + ev_metadata_get_int (window->priv->metadata, "window_y", &y)) { + gtk_window_move (GTK_WINDOW (window), x, y); } - if (ev_metadata_manager_get (uri, "window_width", &width, TRUE) && - ev_metadata_manager_get (uri, "window_height", &height, TRUE)) { - gtk_window_resize (GTK_WINDOW (window), - g_value_get_int (&width), - g_value_get_int (&height)); - g_value_unset (&width); - g_value_unset (&height); + if (ev_metadata_get_int (window->priv->metadata, "window_width", &width) && + ev_metadata_get_int (window->priv->metadata, "window_height", &height)) { + gtk_window_resize (GTK_WINDOW (window), width, height); } } static void setup_view_from_metadata (EvWindow *window) { - EvView *view = EV_VIEW (window->priv->view); - gchar *uri = window->priv->uri; - GValue continuous = { 0, }; - GValue dual_page = { 0, }; - GValue presentation = { 0, }; - GValue fullscreen = { 0, }; - - /* Continuous */ - if (ev_metadata_manager_get (uri, "continuous", &continuous, FALSE)) { - ev_view_set_continuous (view, g_value_get_boolean (&continuous)); - g_value_unset (&continuous); - } + gboolean presentation; - /* Dual page */ - if (ev_metadata_manager_get (uri, "dual-page", &dual_page, FALSE)) { - ev_view_set_dual_page (view, g_value_get_boolean (&dual_page)); - g_value_unset (&dual_page); - } + if (!window->priv->metadata) + return; /* Presentation */ - if (ev_metadata_manager_get (uri, "presentation", &presentation, FALSE)) { - if (g_value_get_boolean (&presentation) && uri) { + if (ev_metadata_get_boolean (window->priv->metadata, "presentation", &presentation)) { + if (presentation) { ev_window_run_presentation (window); } - g_value_unset (&presentation); - } - - /* Fullscreen */ - if (ev_metadata_manager_get (uri, "fullscreen", &fullscreen, FALSE)) { - if (g_value_get_boolean (&fullscreen) && uri) { - ev_window_run_fullscreen (window); - } - g_value_unset (&fullscreen); } } @@ -1153,6 +1300,8 @@ ev_window_set_icon_from_thumbnail (EvJobThumbnail *job, EvWindow *ev_window) { if (job->thumbnail) { + if (ev_document_model_get_inverted_colors (ev_window->priv->model)) + ev_document_misc_invert_pixbuf (job->thumbnail); gtk_window_set_icon (GTK_WINDOW (ev_window), job->thumbnail); } @@ -1161,14 +1310,14 @@ ev_window_set_icon_from_thumbnail (EvJobThumbnail *job, } static void -ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation) +ev_window_refresh_window_thumbnail (EvWindow *ev_window) { gdouble page_width; gdouble scale; + gint rotation; EvDocument *document = ev_window->priv->document; - if (!EV_IS_DOCUMENT_THUMBNAILS (document) || - ev_document_get_n_pages (document) <= 0 || + if (ev_document_get_n_pages (document) <= 0 || !ev_document_check_dimensions (document)) { return; } @@ -1177,6 +1326,7 @@ ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation) ev_document_get_page_size (document, 0, &page_width, NULL); scale = 128. / page_width; + rotation = ev_document_model_get_rotation (ev_window->priv->model); ev_window->priv->thumbnail_job = ev_job_thumbnail_new (document, 0, rotation, scale); g_signal_connect (ev_window->priv->thumbnail_job, "finished", @@ -1185,6 +1335,22 @@ ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation) ev_job_scheduler_push_job (ev_window->priv->thumbnail_job, EV_JOB_PRIORITY_NONE); } +static void +override_restrictions_changed (GSettings *settings, + gchar *key, + EvWindow *ev_window) +{ + ev_window_setup_action_sensitivity (ev_window); +} + +static void +lockdown_changed (GSettings *lockdown, + const gchar *key, + EvWindow *ev_window) +{ + ev_window_setup_action_sensitivity (ev_window); +} + static gboolean ev_window_setup_document (EvWindow *ev_window) { @@ -1193,13 +1359,31 @@ ev_window_setup_document (EvWindow *ev_window) GtkAction *action; ev_window->priv->setup_document_idle = 0; - - ev_window_refresh_window_thumbnail (ev_window, 0); + + ev_window_refresh_window_thumbnail (ev_window); ev_window_set_page_mode (ev_window, PAGE_MODE_DOCUMENT); ev_window_title_set_document (ev_window->priv->title, document); ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri); + if (!ev_window->priv->settings) { + ev_window->priv->settings = g_settings_new (GS_SCHEMA_NAME); + g_signal_connect (ev_window->priv->settings, + "changed::"GS_OVERRIDE_RESTRICTIONS, + G_CALLBACK (override_restrictions_changed), + ev_window); + } + +#ifdef HAVE_DESKTOP_SCHEMAS + if (!ev_window->priv->lockdown_settings) { + ev_window->priv->lockdown_settings = g_settings_new (GS_LOCKDOWN_SCHEMA_NAME); + g_signal_connect (ev_window->priv->lockdown_settings, + "changed", + G_CALLBACK (lockdown_changed), + ev_window); + } +#endif + ev_window_setup_action_sensitivity (ev_window); if (ev_window->priv->history) @@ -1217,7 +1401,10 @@ ev_window_setup_document (EvWindow *ev_window) info = ev_document_get_info (document); update_document_mode (ev_window, info->mode); - gtk_widget_grab_focus (ev_window->priv->view); + if (EV_WINDOW_IS_PRESENTATION (ev_window)) + gtk_widget_grab_focus (ev_window->priv->presentation_view); + else + gtk_widget_grab_focus (ev_window->priv->view); return FALSE; } @@ -1232,19 +1419,9 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) g_object_unref (ev_window->priv->document); ev_window->priv->document = g_object_ref (document); - ev_window_set_message_area (ev_window, NULL); - - if (ev_window->priv->in_reload && ev_window->priv->dest) { - gint page; + ev_window_update_max_min_scale (ev_window); - /* Restart the current page */ - page = CLAMP (ev_link_dest_get_page (ev_window->priv->dest), - 0, - ev_document_get_n_pages (document) - 1); - ev_document_model_set_page (ev_window->priv->model, page); - g_object_unref (ev_window->priv->dest); - ev_window->priv->dest = NULL; - } + ev_window_set_message_area (ev_window, NULL); if (ev_document_get_n_pages (document) <= 0) { ev_window_warning_message (ev_window, "%s", @@ -1254,6 +1431,12 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) _("The document contains only empty pages")); } + if (EV_WINDOW_IS_PRESENTATION (ev_window)) { + gtk_widget_destroy (ev_window->priv->presentation_view); + ev_window->priv->presentation_view = NULL; + ev_window_run_presentation (ev_window); + } + if (ev_window->priv->setup_document_idle > 0) g_source_remove (ev_window->priv->setup_document_idle); @@ -1354,6 +1537,11 @@ ev_window_load_job_cb (EvJob *job, if (!ev_job_is_failed (job)) { ev_document_model_set_document (ev_window->priv->model, document); +#ifdef ENABLE_DBUS + ev_window_emit_doc_loaded (ev_window); +#endif + setup_chrome_from_metadata (ev_window); + update_chrome_actions (ev_window); setup_document_from_metadata (ev_window); setup_view_from_metadata (ev_window); @@ -1455,23 +1643,28 @@ ev_window_reload_job_cb (EvJob *job, EvWindow *ev_window) { GtkWidget *widget; - EvLinkDest *dest = NULL; if (ev_job_is_failed (job)) { ev_window_clear_reload_job (ev_window); ev_window->priv->in_reload = FALSE; - g_object_unref (ev_window->priv->dest); - ev_window->priv->dest = NULL; - + if (ev_window->priv->dest) { + g_object_unref (ev_window->priv->dest); + ev_window->priv->dest = NULL; + } + return; } - if (ev_window->priv->dest) { - dest = g_object_ref (ev_window->priv->dest); - } ev_document_model_set_document (ev_window->priv->model, job->document); - ev_window_handle_link (ev_window, dest); + if (ev_window->priv->dest) { + ev_window_handle_link (ev_window, ev_window->priv->dest); + /* Already unrefed by ev_link_action + * FIXME: link action should inc dest ref counting + * or not unref it at all + */ + ev_window->priv->dest = NULL; + } /* Restart the search after reloading */ widget = gtk_window_get_focus (GTK_WINDOW (ev_window)); @@ -1574,7 +1767,9 @@ show_loading_progress (EvWindow *ev_window) if (ev_window->priv->message_area) return FALSE; - display_name = escape_uri_for_display (ev_window->priv->uri); + text = g_uri_unescape_string (ev_window->priv->uri, NULL); + display_name = g_markup_escape_text (text, -1); + g_free (text); text = g_strdup_printf (_("Loading document from “%s”"), display_name); @@ -1662,7 +1857,8 @@ window_open_file_copy_ready_cb (GFile *source, GError *error = NULL; ev_window_clear_progress_idle (ev_window); - + ev_window_set_message_area (ev_window, NULL); + g_file_copy_finish (source, async_result, &error); if (!error) { ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE); @@ -1712,6 +1908,9 @@ window_open_file_copy_progress_cb (goffset n_bytes, if (!ev_window->priv->message_area) return; + if (total_bytes <= 0) + return; + fraction = n_bytes / (gdouble)total_bytes; status = g_strdup_printf (_("Downloading document (%d%%)"), (gint)(fraction * 100)); @@ -1731,26 +1930,39 @@ ev_window_load_file_remote (EvWindow *ev_window, GFile *target_file; if (!ev_window->priv->local_uri) { - gchar *tmp_name; - gchar *base_name; + char *base_name, *template; + GFile *tmp_file; + GError *err = NULL; /* We'd like to keep extension of source uri since - * it helps to resolve some mime types, say cbz */ - tmp_name = ev_tmp_filename (NULL); + * it helps to resolve some mime types, say cbz. + */ base_name = g_file_get_basename (source_file); - ev_window->priv->local_uri = g_strconcat ("file:", tmp_name, "-", - base_name, NULL); + template = g_strdup_printf ("document.XXXXXX-%s", base_name); + g_free (base_name); + + tmp_file = ev_mkstemp_file (template, &err); + g_free (template); + if (tmp_file == NULL) { + ev_window_error_message (ev_window, err, + "%s", _("Failed to load remote file.")); + g_error_free (err); + return; + } + + ev_window->priv->local_uri = g_file_get_uri (tmp_file); + g_object_unref (tmp_file); + ev_job_load_set_uri (EV_JOB_LOAD (ev_window->priv->load_job), ev_window->priv->local_uri); - g_free (base_name); - g_free (tmp_name); } ev_window_reset_progress_cancellable (ev_window); target_file = g_file_new_for_uri (ev_window->priv->local_uri); g_file_copy_async (source_file, target_file, - 0, G_PRIORITY_DEFAULT, + G_FILE_COPY_OVERWRITE, + G_PRIORITY_DEFAULT, ev_window->priv->progress_cancellable, (GFileProgressCallback)window_open_file_copy_progress_cb, ev_window, @@ -1787,7 +1999,6 @@ ev_window_open_uri (EvWindow *ev_window, ev_window_close_dialogs (ev_window); ev_window_clear_load_job (ev_window); ev_window_clear_local_uri (ev_window); - ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE); ev_window->priv->window_mode = mode; @@ -1795,6 +2006,17 @@ ev_window_open_uri (EvWindow *ev_window, g_free (ev_window->priv->uri); ev_window->priv->uri = g_strdup (uri); + if (ev_window->priv->metadata) + g_object_unref (ev_window->priv->metadata); + + source_file = g_file_new_for_uri (uri); + if (!ev_file_is_temp (source_file) && ev_is_metadata_supported_for_file (source_file)) { + ev_window->priv->metadata = ev_metadata_new (source_file); + ev_window->priv->is_new_doc = ev_metadata_is_empty (ev_window->priv->metadata); + } else { + ev_window->priv->metadata = NULL; + } + if (ev_window->priv->search_string) g_free (ev_window->priv->search_string); ev_window->priv->search_string = search_string ? @@ -1813,10 +2035,10 @@ ev_window_open_uri (EvWindow *ev_window, G_CALLBACK (ev_window_load_job_cb), ev_window); - source_file = g_file_new_for_uri (uri); if (!g_file_is_native (source_file) && !ev_window->priv->local_uri) { ev_window_load_file_remote (ev_window, source_file); } else { + ev_view_set_loading (EV_VIEW (ev_window->priv->view), TRUE); g_object_unref (source_file); ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE); } @@ -1964,7 +2186,10 @@ reload_remote_copy_progress_cb (goffset n_bytes, if (!ev_window->priv->message_area) return; - + + if (total_bytes <= 0) + return; + fraction = n_bytes / (gdouble)total_bytes; status = g_strdup_printf (_("Downloading document (%d%%)"), (gint)(fraction * 100)); @@ -2053,8 +2278,7 @@ ev_window_reload_document (EvWindow *ev_window, if (ev_window->priv->dest) g_object_unref (ev_window->priv->dest); - /* FIXME: save the scroll position too (xyz dest) */ - ev_window->priv->dest = dest ? g_object_ref (dest) : ev_link_dest_new_page (page); + ev_window->priv->dest = dest ? g_object_ref (dest) : NULL; if (ev_window->priv->local_uri) { ev_window_reload_remote (ev_window); @@ -2076,7 +2300,7 @@ file_open_dialog_response_cb (GtkWidget *chooser, ev_application_open_uri_list (EV_APP, uris, gtk_window_get_screen (GTK_WINDOW (ev_window)), - GDK_CURRENT_TIME); + gtk_get_current_event_time ()); g_slist_foreach (uris, (GFunc)g_free, NULL); g_slist_free (uris); @@ -2146,12 +2370,16 @@ static void ev_window_open_copy_at_dest (EvWindow *window, EvLinkDest *dest) { - GtkWidget *new_window = ev_window_new (); + EvWindow *new_window = EV_WINDOW (ev_window_new ()); - ev_window_open_document (EV_WINDOW (new_window), + ev_window_n_copies++; + + if (window->priv->metadata) + new_window->priv->metadata = g_object_ref (window->priv->metadata); + ev_window_open_document (new_window, window->priv->document, dest, 0, NULL); - gtk_widget_show (new_window); + gtk_window_present (GTK_WINDOW (new_window)); } static void @@ -2174,7 +2402,7 @@ ev_window_cmd_recent_file_activate (GtkAction *action, ev_application_open_uri_at_dest (EV_APP, uri, gtk_window_get_screen (GTK_WINDOW (window)), - NULL, 0, NULL, GDK_CURRENT_TIME); + NULL, 0, NULL, gtk_get_current_event_time ()); } static void @@ -2184,7 +2412,7 @@ ev_window_open_recent_action_item_activated (EvOpenRecentAction *action, { ev_application_open_uri_at_dest (EV_APP, uri, gtk_window_get_screen (GTK_WINDOW (window)), - NULL, 0, NULL, GDK_CURRENT_TIME); + NULL, 0, NULL, gtk_get_current_event_time ()); } static void @@ -2260,6 +2488,23 @@ ev_window_get_recent_file_label (gint index, const gchar *filename) return g_string_free (str, FALSE); } +static void +ev_window_recent_action_connect_proxy_cb (GtkActionGroup *action_group, + GtkAction *action, + GtkWidget *proxy, + gpointer data) +{ + GtkLabel *label; + + if (!GTK_IS_MENU_ITEM (proxy)) + return; + + label = GTK_LABEL (gtk_bin_get_child (GTK_BIN (proxy))); + + gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_MIDDLE); + gtk_label_set_max_width_chars (label, MAX_RECENT_ITEM_LEN); +} + static void ev_window_setup_recent (EvWindow *ev_window) { @@ -2281,8 +2526,11 @@ ev_window_setup_recent (EvWindow *ev_window) g_object_unref (ev_window->priv->recent_action_group); } ev_window->priv->recent_action_group = gtk_action_group_new ("RecentFilesActions"); + g_signal_connect (ev_window->priv->recent_action_group, "connect-proxy", + G_CALLBACK (ev_window_recent_action_connect_proxy_cb), NULL); + gtk_ui_manager_insert_action_group (ev_window->priv->ui_manager, - ev_window->priv->recent_action_group, 0); + ev_window->priv->recent_action_group, -1); items = gtk_recent_manager_get_items (ev_window->priv->recent_manager); items = g_list_sort (items, (GCompareFunc) compare_recent_items); @@ -2292,6 +2540,9 @@ ev_window_setup_recent (EvWindow *ev_window) GtkAction *action; gchar *action_name; gchar *label; + const gchar *mime_type; + gchar *content_type; + GIcon *icon = NULL; info = (GtkRecentInfo *) l->data; @@ -2302,10 +2553,19 @@ ev_window_setup_recent (EvWindow *ev_window) action_name = g_strdup_printf ("RecentFile%u", i++); label = ev_window_get_recent_file_label ( n_items + 1, gtk_recent_info_get_display_name (info)); - + + mime_type = gtk_recent_info_get_mime_type (info); + content_type = g_content_type_from_mime_type (mime_type); + if (content_type != NULL) { + icon = g_content_type_get_icon (content_type); + g_free (content_type); + } + action = g_object_new (GTK_TYPE_ACTION, "name", action_name, "label", label, + "gicon", icon, + "always-show-image", TRUE, NULL); g_object_set_data_full (G_OBJECT (action), @@ -2330,6 +2590,8 @@ ev_window_setup_recent (EvWindow *ev_window) FALSE); g_free (action_name); g_free (label); + if (icon != NULL) + g_object_unref (icon); if (++n_items == 5) break; @@ -2430,7 +2692,10 @@ window_save_file_copy_progress_cb (goffset n_bytes, if (!ev_window->priv->message_area) return; - + + if (total_bytes <= 0) + return; + fraction = n_bytes / (gdouble)total_bytes; save_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dst), "save-type")); @@ -2507,6 +2772,8 @@ ev_window_save_job_cb (EvJob *job, ev_window_error_message (window, job->error, _("The file could not be saved as “%s”."), EV_JOB_SAVE (job)->uri); + } else { + ev_window_add_recent (window, EV_JOB_SAVE (job)->uri); } ev_window_clear_save_job (window); @@ -2607,148 +2874,261 @@ ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window) } static void -ev_window_load_print_settings_from_metadata (EvWindow *window) +ev_window_cmd_open_containing_folder (GtkAction *action, EvWindow *ev_window) { - gchar *uri = window->priv->uri; - gint i; - - /* Load print setting that are specific to the document */ - for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) { - GValue value = { 0, }; - gboolean success; + GtkWidget *ev_window_widget; + GFile *file; + GFile *parent; + + ev_window_widget = GTK_WIDGET (ev_window); + + file = g_file_new_for_uri (ev_window->priv->uri); + parent = g_file_get_parent (file); + + if (parent) { + char *parent_uri; + + parent_uri = g_file_get_uri (parent); + if (parent_uri) { + GdkScreen *screen; + guint32 timestamp; + GError *error; + + screen = gtk_widget_get_screen (ev_window_widget); + timestamp = gtk_get_current_event_time (); - success = ev_metadata_manager_get (uri, document_print_settings[i], &value, TRUE); - gtk_print_settings_set (window->priv->print_settings, - document_print_settings[i], - success ? g_value_get_string (&value) : NULL); - if (success) - g_value_unset (&value); + error = NULL; + if (!gtk_show_uri (screen, parent_uri, timestamp, &error)) { + ev_window_error_message (ev_window, error, _("Could not open the containing folder")); + g_error_free (error); + } + + g_free (parent_uri); + } } + + if (file) + g_object_unref (file); + + if (parent) + g_object_unref (parent); + +} + +static GKeyFile * +get_print_settings_file (void) +{ + GKeyFile *print_settings_file; + gchar *filename; + GError *error = NULL; + + print_settings_file = g_key_file_new (); + + filename = g_build_filename (ev_application_get_dot_dir (EV_APP, FALSE), + EV_PRINT_SETTINGS_FILE, NULL); + if (!g_key_file_load_from_file (print_settings_file, + filename, + G_KEY_FILE_KEEP_COMMENTS | + G_KEY_FILE_KEEP_TRANSLATIONS, + &error)) { + + /* Don't warn if the file simply doesn't exist */ + if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + g_warning ("%s", error->message); + + g_error_free (error); + } + + g_free (filename); + + return print_settings_file; } static void -ev_window_save_print_settings (EvWindow *window) +save_print_setting_file (GKeyFile *key_file) { - gchar *uri = window->priv->uri; - gint i; - + gchar *filename; + gchar *data; + gsize data_length; + GError *error = NULL; + + filename = g_build_filename (ev_application_get_dot_dir (EV_APP, TRUE), + EV_PRINT_SETTINGS_FILE, NULL); + data = g_key_file_to_data (key_file, &data_length, NULL); + g_file_set_contents (filename, data, data_length, &error); + if (error) { + g_warning ("Failed to save print settings: %s", error->message); + g_error_free (error); + } + g_free (data); + g_free (filename); +} + +static void +ev_window_save_print_settings (EvWindow *window, + GtkPrintSettings *print_settings) +{ + GKeyFile *key_file; + gint i; + + key_file = get_print_settings_file (); + gtk_print_settings_to_key_file (print_settings, key_file, EV_PRINT_SETTINGS_GROUP); + /* Save print settings that are specific to the document */ for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) { - const gchar *value; + /* Remove it from global settings */ + g_key_file_remove_key (key_file, EV_PRINT_SETTINGS_GROUP, + document_print_settings[i], NULL); - value = gtk_print_settings_get (window->priv->print_settings, - document_print_settings[i]); - ev_metadata_manager_set_string (uri, document_print_settings[i], value); + if (window->priv->metadata) { + const gchar *value; + + value = gtk_print_settings_get (print_settings, + document_print_settings[i]); + ev_metadata_set_string (window->priv->metadata, + document_print_settings[i], value); + } } + + save_print_setting_file (key_file); + g_key_file_free (key_file); } static void -ev_window_save_print_page_setup (EvWindow *window) +ev_window_save_print_page_setup (EvWindow *window, + GtkPageSetup *page_setup) { - gchar *uri = window->priv->uri; - GtkPageSetup *page_setup = window->priv->print_page_setup; + GKeyFile *key_file; + + key_file = get_print_settings_file (); + gtk_page_setup_to_key_file (page_setup, key_file, EV_PAGE_SETUP_GROUP); + + /* Do not save document settings in global file */ + g_key_file_remove_key (key_file, EV_PAGE_SETUP_GROUP, + "page-setup-orientation", NULL); + g_key_file_remove_key (key_file, EV_PAGE_SETUP_GROUP, + "page-setup-margin-top", NULL); + g_key_file_remove_key (key_file, EV_PAGE_SETUP_GROUP, + "page-setup-margin-bottom", NULL); + g_key_file_remove_key (key_file, EV_PAGE_SETUP_GROUP, + "page-setup-margin-left", NULL); + g_key_file_remove_key (key_file, EV_PAGE_SETUP_GROUP, + "page-setup-margin-right", NULL); + + save_print_setting_file (key_file); + g_key_file_free (key_file); + + if (!window->priv->metadata) + return; /* Save page setup options that are specific to the document */ - ev_metadata_manager_set_int (uri, "page-setup-orientation", - gtk_page_setup_get_orientation (page_setup)); - ev_metadata_manager_set_double (uri, "page-setup-margin-top", - gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM)); - ev_metadata_manager_set_double (uri, "page-setup-margin-bottom", - gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM)); - ev_metadata_manager_set_double (uri, "page-setup-margin-left", - gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM)); - ev_metadata_manager_set_double (uri, "page-setup-margin-right", - gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM)); + ev_metadata_set_int (window->priv->metadata, "page-setup-orientation", + gtk_page_setup_get_orientation (page_setup)); + ev_metadata_set_double (window->priv->metadata, "page-setup-margin-top", + gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM)); + ev_metadata_set_double (window->priv->metadata, "page-setup-margin-bottom", + gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM)); + ev_metadata_set_double (window->priv->metadata, "page-setup-margin-left", + gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM)); + ev_metadata_set_double (window->priv->metadata, "page-setup-margin-right", + gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM)); } static void -ev_window_load_print_page_setup_from_metadata (EvWindow *window) +ev_window_load_print_settings_from_metadata (EvWindow *window, + GtkPrintSettings *print_settings) { - gchar *uri = window->priv->uri; - GtkPageSetup *page_setup = window->priv->print_page_setup; - GtkPaperSize *paper_size; - GValue value = { 0, }; + gint i; + + if (!window->priv->metadata) + return; + + /* Load print setting that are specific to the document */ + for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) { + gchar *value = NULL; + + ev_metadata_get_string (window->priv->metadata, + document_print_settings[i], &value); + gtk_print_settings_set (print_settings, + document_print_settings[i], value); + } +} + +static void +ev_window_load_print_page_setup_from_metadata (EvWindow *window, + GtkPageSetup *page_setup) +{ + gint int_value; + gdouble double_value; + GtkPaperSize *paper_size = gtk_page_setup_get_paper_size (page_setup); - paper_size = gtk_page_setup_get_paper_size (page_setup); - /* Load page setup options that are specific to the document */ - if (ev_metadata_manager_get (uri, "page-setup-orientation", &value, TRUE)) { - gtk_page_setup_set_orientation (page_setup, g_value_get_int (&value)); - g_value_unset (&value); + if (window->priv->metadata && + ev_metadata_get_int (window->priv->metadata, "page-setup-orientation", &int_value)) { + gtk_page_setup_set_orientation (page_setup, int_value); } else { gtk_page_setup_set_orientation (page_setup, GTK_PAGE_ORIENTATION_PORTRAIT); } - - if (ev_metadata_manager_get (uri, "page-setup-margin-top", &value, TRUE)) { - gtk_page_setup_set_top_margin (page_setup, g_value_get_double (&value), GTK_UNIT_MM); - g_value_unset (&value); + + if (window->priv->metadata && + ev_metadata_get_double (window->priv->metadata, "page-setup-margin-top", &double_value)) { + gtk_page_setup_set_top_margin (page_setup, double_value, GTK_UNIT_MM); } else { gtk_page_setup_set_top_margin (page_setup, gtk_paper_size_get_default_top_margin (paper_size, GTK_UNIT_MM), GTK_UNIT_MM); } - if (ev_metadata_manager_get (uri, "page-setup-margin-bottom", &value, TRUE)) { - gtk_page_setup_set_bottom_margin (page_setup, g_value_get_double (&value), GTK_UNIT_MM); - g_value_unset (&value); + if (window->priv->metadata && + ev_metadata_get_double (window->priv->metadata, "page-setup-margin-bottom", &double_value)) { + gtk_page_setup_set_bottom_margin (page_setup, double_value, GTK_UNIT_MM); } else { gtk_page_setup_set_bottom_margin (page_setup, gtk_paper_size_get_default_bottom_margin (paper_size, GTK_UNIT_MM), GTK_UNIT_MM); } - if (ev_metadata_manager_get (uri, "page-setup-margin-left", &value, TRUE)) { - gtk_page_setup_set_left_margin (page_setup, g_value_get_double (&value), GTK_UNIT_MM); - g_value_unset (&value); + if (window->priv->metadata && + ev_metadata_get_double (window->priv->metadata, "page-setup-margin-left", &double_value)) { + gtk_page_setup_set_left_margin (page_setup, double_value, GTK_UNIT_MM); } else { gtk_page_setup_set_left_margin (page_setup, gtk_paper_size_get_default_left_margin (paper_size, GTK_UNIT_MM), GTK_UNIT_MM); - } + } - if (ev_metadata_manager_get (uri, "page-setup-margin-right", &value, TRUE)) { - gtk_page_setup_set_right_margin (page_setup, g_value_get_double (&value), GTK_UNIT_MM); - g_value_unset (&value); + if (window->priv->metadata && + ev_metadata_get_double (window->priv->metadata, "page-setup-margin-right", &double_value)) { + gtk_page_setup_set_right_margin (page_setup, double_value, GTK_UNIT_MM); } else { gtk_page_setup_set_right_margin (page_setup, gtk_paper_size_get_default_right_margin (paper_size, GTK_UNIT_MM), GTK_UNIT_MM); - } + } } -static void -ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup, - EvWindow *window) +static GtkPrintSettings * +get_print_settings (GKeyFile *key_file) { - /* Dialog was canceled */ - if (!page_setup) - return; + GtkPrintSettings *print_settings; - if (window->priv->print_page_setup != page_setup) { - if (window->priv->print_page_setup) - g_object_unref (window->priv->print_page_setup); - window->priv->print_page_setup = g_object_ref (page_setup); - } - - ev_application_set_page_setup (EV_APP, page_setup); - ev_window_save_print_page_setup (window); + print_settings = g_key_file_has_group (key_file, EV_PRINT_SETTINGS_GROUP) ? + gtk_print_settings_new_from_key_file (key_file, EV_PRINT_SETTINGS_GROUP, NULL) : + gtk_print_settings_new (); + + return print_settings ? print_settings : gtk_print_settings_new (); } -static void -ev_window_cmd_file_print_setup (GtkAction *action, EvWindow *ev_window) +static GtkPageSetup * +get_print_page_setup (GKeyFile *key_file) { - if (!ev_window->priv->print_page_setup) { - ev_window->priv->print_page_setup = gtk_page_setup_copy ( - ev_application_get_page_setup (EV_APP)); - ev_window_load_print_page_setup_from_metadata (ev_window); - } - - gtk_print_run_page_setup_dialog_async ( - GTK_WINDOW (ev_window), - ev_window->priv->print_page_setup, - ev_window->priv->print_settings, - (GtkPageSetupDoneFunc) ev_window_print_page_setup_done_cb, - ev_window); + GtkPageSetup *page_setup; + + page_setup = g_key_file_has_group (key_file, EV_PAGE_SETUP_GROUP) ? + gtk_page_setup_new_from_key_file (key_file, EV_PAGE_SETUP_GROUP, NULL) : + gtk_page_setup_new (); + + return page_setup ? page_setup : gtk_page_setup_new (); } static void @@ -2804,20 +3184,20 @@ ev_window_print_operation_done (EvPrintOperation *op, EvWindow *ev_window) { gint n_jobs; - + switch (result) { case GTK_PRINT_OPERATION_RESULT_APPLY: { GtkPrintSettings *print_settings; - + print_settings = ev_print_operation_get_print_settings (op); - if (ev_window->priv->print_settings != print_settings) { - if (ev_window->priv->print_settings) - g_object_unref (ev_window->priv->print_settings); - ev_window->priv->print_settings = g_object_ref (print_settings); + ev_window_save_print_settings (ev_window, print_settings); + + if (ev_print_operation_get_embed_page_setup (op)) { + GtkPageSetup *page_setup; + + page_setup = ev_print_operation_get_default_page_setup (op); + ev_window_save_print_page_setup (ev_window, page_setup); } - - ev_application_set_print_settings (EV_APP, print_settings); - ev_window_save_print_settings (ev_window); } break; @@ -2921,19 +3301,12 @@ static void ev_window_print_operation_begin_print (EvPrintOperation *op, EvWindow *ev_window) { - GtkPrintSettings *print_settings; - if (!ev_window->priv->print_queue) ev_window->priv->print_queue = g_queue_new (); g_queue_push_head (ev_window->priv->print_queue, op); ev_window_print_update_pending_jobs_message (ev_window, g_queue_get_length (ev_window->priv->print_queue)); - - if (ev_window->priv->print_settings) - g_object_unref (ev_window->priv->print_settings); - print_settings = ev_print_operation_get_print_settings (op); - ev_window->priv->print_settings = g_object_ref (print_settings); } void @@ -2942,8 +3315,12 @@ ev_window_print_range (EvWindow *ev_window, gint last_page) { EvPrintOperation *op; + GKeyFile *print_settings_file; + GtkPrintSettings *print_settings; + GtkPageSetup *print_page_setup; gint current_page; gint document_last_page; + gboolean embed_page_setup; g_return_if_fail (EV_IS_WINDOW (ev_window)); g_return_if_fail (ev_window->priv->document != NULL); @@ -2970,17 +3347,13 @@ ev_window_print_range (EvWindow *ev_window, current_page = ev_document_model_get_page (ev_window->priv->model); document_last_page = ev_document_get_n_pages (ev_window->priv->document); - if (!ev_window->priv->print_settings) { - ev_window->priv->print_settings = gtk_print_settings_copy ( - ev_application_get_print_settings (EV_APP)); - ev_window_load_print_settings_from_metadata (ev_window); - } + print_settings_file = get_print_settings_file (); - if (!ev_window->priv->print_page_setup) { - ev_window->priv->print_page_setup = gtk_page_setup_copy ( - ev_application_get_page_setup (EV_APP)); - ev_window_load_print_page_setup_from_metadata (ev_window); - } + print_settings = get_print_settings (print_settings_file); + ev_window_load_print_settings_from_metadata (ev_window, print_settings); + + print_page_setup = get_print_page_setup (print_settings_file); + ev_window_load_print_page_setup_from_metadata (ev_window, print_page_setup); if (first_page != 1 || last_page != document_last_page) { GtkPageRange range; @@ -2988,17 +3361,26 @@ ev_window_print_range (EvWindow *ev_window, /* Ranges in GtkPrint are 0 - N */ range.start = first_page - 1; range.end = last_page - 1; - - gtk_print_settings_set_print_pages (ev_window->priv->print_settings, + + gtk_print_settings_set_print_pages (print_settings, GTK_PRINT_PAGES_RANGES); - gtk_print_settings_set_page_ranges (ev_window->priv->print_settings, + gtk_print_settings_set_page_ranges (print_settings, &range, 1); } ev_print_operation_set_job_name (op, gtk_window_get_title (GTK_WINDOW (ev_window))); ev_print_operation_set_current_page (op, current_page); - ev_print_operation_set_print_settings (op, ev_window->priv->print_settings); - ev_print_operation_set_default_page_setup (op, ev_window->priv->print_page_setup); + ev_print_operation_set_print_settings (op, print_settings); + ev_print_operation_set_default_page_setup (op, print_page_setup); + embed_page_setup = ev_window->priv->lockdown_settings ? + !g_settings_get_boolean (ev_window->priv->lockdown_settings, + GS_LOCKDOWN_PRINT_SETUP) : + TRUE; + ev_print_operation_set_embed_page_setup (op, embed_page_setup); + + g_object_unref (print_settings); + g_object_unref (print_page_setup); + g_key_file_free (print_settings_file); ev_print_operation_run (op, GTK_WINDOW (ev_window)); } @@ -3035,6 +3417,91 @@ ev_window_cmd_file_properties (GtkAction *action, EvWindow *ev_window) ev_document_fc_mutex_unlock (); } +static void +document_modified_confirmation_dialog_response (GtkDialog *dialog, + gint response, + EvWindow *ev_window) +{ + gtk_widget_destroy (GTK_WIDGET (dialog)); + + switch (response) { + case GTK_RESPONSE_YES: + ev_window_cmd_save_as (NULL, ev_window); + break; + case GTK_RESPONSE_NO: + gtk_widget_destroy (GTK_WIDGET (ev_window)); + break; + case GTK_RESPONSE_CANCEL: + default: + break; + } +} + +static gboolean +ev_window_check_document_modified (EvWindow *ev_window) +{ + EvDocument *document = ev_window->priv->document; + GtkWidget *dialog; + gchar *text, *markup; + const gchar *secondary_text; + + if (!document) + return FALSE; + + if (EV_IS_DOCUMENT_FORMS (document) && + ev_document_forms_document_is_modified (EV_DOCUMENT_FORMS (document))) { + secondary_text = _("Document contains form fields that have been filled out. " + "If you don't save a copy, changes will be permanently lost."); + } else if (EV_IS_DOCUMENT_ANNOTATIONS (document) && + ev_document_annotations_document_is_modified (EV_DOCUMENT_ANNOTATIONS (document))) { + secondary_text = _("Document contains new or modified annotations. " + "If you don't save a copy, changes will be permanently lost."); + } else { + return FALSE; + } + + + text = g_markup_printf_escaped (_("Save a copy of document “%s” before closing?"), + gtk_window_get_title (GTK_WINDOW (ev_window))); + + dialog = gtk_message_dialog_new (GTK_WINDOW (ev_window), + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + NULL); + + markup = g_strdup_printf ("%s", text); + g_free (text); + + gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), markup); + g_free (markup); + + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + "%s", secondary_text); + + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + _("Close _without Saving"), + GTK_RESPONSE_NO, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + _("Save a _Copy"), + GTK_RESPONSE_YES, + NULL); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); + gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), + GTK_RESPONSE_YES, + GTK_RESPONSE_NO, + GTK_RESPONSE_CANCEL, + -1); + + g_signal_connect (dialog, "response", + G_CALLBACK (document_modified_confirmation_dialog_response), + ev_window); + gtk_widget_show (dialog); + + return TRUE; +} + static void print_jobs_confirmation_dialog_response (GtkDialog *dialog, gint response, @@ -3066,8 +3533,8 @@ print_jobs_confirmation_dialog_response (GtkDialog *dialog, } } -static void -ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window) +static gboolean +ev_window_check_print_queue (EvWindow *ev_window) { GtkWidget *dialog; gchar *text, *markup; @@ -3075,11 +3542,9 @@ ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window) n_print_jobs = ev_window->priv->print_queue ? g_queue_get_length (ev_window->priv->print_queue) : 0; - - if (n_print_jobs == 0) { - gtk_widget_destroy (GTK_WIDGET (ev_window)); - return; - } + + if (n_print_jobs == 0) + return FALSE; dialog = gtk_message_dialog_new (GTK_WINDOW (ev_window), GTK_DIALOG_MODAL, @@ -3110,7 +3575,7 @@ ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window) gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", _("If you close the window, pending print " "jobs will not be printed.")); - + gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("Cancel _print and Close"), GTK_RESPONSE_NO, @@ -3130,6 +3595,36 @@ ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window) G_CALLBACK (print_jobs_confirmation_dialog_response), ev_window); gtk_widget_show (dialog); + + return TRUE; +} + +static gboolean +ev_window_close (EvWindow *ev_window) +{ + if (EV_WINDOW_IS_PRESENTATION (ev_window)) { + gint current_page; + + /* Save current page */ + current_page = ev_view_presentation_get_current_page ( + EV_VIEW_PRESENTATION (ev_window->priv->presentation_view)); + ev_document_model_set_page (ev_window->priv->model, current_page); + } + + if (ev_window_check_document_modified (ev_window)) + return FALSE; + + if (ev_window_check_print_queue (ev_window)) + return FALSE; + + return TRUE; +} + +static void +ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window) +{ + if (ev_window_close (ev_window)) + gtk_widget_destroy (GTK_WIDGET (ev_window)); } static void @@ -3165,10 +3660,7 @@ ev_window_cmd_continuous (GtkAction *action, EvWindow *ev_window) ev_window_stop_presentation (ev_window, TRUE); continuous = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); - g_object_set (G_OBJECT (ev_window->priv->view), - "continuous", continuous, - NULL); - ev_window_update_actions (ev_window); + ev_document_model_set_continuous (ev_window->priv->model, continuous); } static void @@ -3178,10 +3670,7 @@ ev_window_cmd_dual (GtkAction *action, EvWindow *ev_window) ev_window_stop_presentation (ev_window, TRUE); dual_page = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); - g_object_set (G_OBJECT (ev_window->priv->view), - "dual-page", dual_page, - NULL); - ev_window_update_actions (ev_window); + ev_document_model_set_dual_page (ev_window->priv->model, dual_page); } static void @@ -3265,12 +3754,13 @@ ev_window_cmd_edit_copy (GtkAction *action, EvWindow *ev_window) } static void -ev_window_sidebar_position_change_cb (GObject *object, GParamSpec *pspec, - EvWindow *ev_window) +ev_window_sidebar_position_change_cb (GObject *object, + GParamSpec *pspec, + EvWindow *ev_window) { - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_int (ev_window->priv->uri, "sidebar_size", - gtk_paned_get_position (GTK_PANED (object))); + if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) + ev_metadata_set_int (ev_window->priv->metadata, "sidebar_size", + gtk_paned_get_position (GTK_PANED (object))); } static void @@ -3282,7 +3772,7 @@ ev_window_update_fullscreen_action (EvWindow *window) g_signal_handlers_block_by_func (action, G_CALLBACK (ev_window_cmd_view_fullscreen), window); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - ev_view_get_fullscreen (EV_VIEW (window->priv->view))); + ev_document_model_get_fullscreen (window->priv->model)); g_signal_handlers_unblock_by_func (action, G_CALLBACK (ev_window_cmd_view_fullscreen), window); } @@ -3329,10 +3819,9 @@ fullscreen_toolbar_remove_shadow (GtkWidget *toolbar) static void ev_window_run_fullscreen (EvWindow *window) { - EvView *view = EV_VIEW (window->priv->view); gboolean fullscreen_window = TRUE; - if (ev_view_get_fullscreen (view)) + if (ev_document_model_get_fullscreen (window->priv->model)) return; if (!window->priv->fullscreen_toolbar) { @@ -3352,7 +3841,7 @@ ev_window_run_fullscreen (EvWindow *window) window->priv->fullscreen_toolbar, 1); } - if (ev_view_get_presentation (view)) { + if (EV_WINDOW_IS_PRESENTATION (window)) { ev_window_stop_presentation (window, FALSE); fullscreen_window = FALSE; } @@ -3361,7 +3850,7 @@ ev_window_run_fullscreen (EvWindow *window) "shadow-type", GTK_SHADOW_NONE, NULL); - ev_view_set_fullscreen (view, TRUE); + ev_document_model_set_fullscreen (window->priv->model, TRUE); ev_window_update_fullscreen_action (window); /* If the user doesn't have the main toolbar he/she won't probably want @@ -3375,32 +3864,30 @@ ev_window_run_fullscreen (EvWindow *window) gtk_window_fullscreen (GTK_WINDOW (window)); gtk_widget_grab_focus (window->priv->view); - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_boolean (window->priv->uri, "fullscreen", TRUE); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "fullscreen", TRUE); } static void ev_window_stop_fullscreen (EvWindow *window, gboolean unfullscreen_window) { - EvView *view = EV_VIEW (window->priv->view); - - if (!ev_view_get_fullscreen (view)) + if (!ev_document_model_get_fullscreen (window->priv->model)) return; g_object_set (G_OBJECT (window->priv->scrolled_window), "shadow-type", GTK_SHADOW_IN, NULL); - ev_view_set_fullscreen (view, FALSE); + ev_document_model_set_fullscreen (window->priv->model, FALSE); ev_window_update_fullscreen_action (window); update_chrome_flag (window, EV_CHROME_FULLSCREEN_TOOLBAR, FALSE); update_chrome_visibility (window); if (unfullscreen_window) gtk_window_unfullscreen (GTK_WINDOW (window)); - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_boolean (window->priv->uri, "fullscreen", FALSE); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "fullscreen", FALSE); } static void @@ -3416,70 +3903,6 @@ ev_window_cmd_view_fullscreen (GtkAction *action, EvWindow *window) } } -static gboolean -presentation_timeout_cb (EvWindow *window) -{ - EvView *view = EV_VIEW (window->priv->view); - - if (!view || !ev_view_get_presentation (EV_VIEW (view))) - return FALSE; - - ev_view_hide_cursor (EV_VIEW (window->priv->view)); - window->priv->presentation_timeout_id = 0; - - return FALSE; -} - -static void -presentation_set_timeout (EvWindow *window) -{ - if (window->priv->presentation_timeout_id > 0) { - g_source_remove (window->priv->presentation_timeout_id); - } - - window->priv->presentation_timeout_id = - g_timeout_add_seconds (PRESENTATION_TIMEOUT, - (GSourceFunc)presentation_timeout_cb, window); - - ev_view_show_cursor (EV_VIEW (window->priv->view)); -} - -static void -presentation_clear_timeout (EvWindow *window) -{ - if (window->priv->presentation_timeout_id > 0) { - g_source_remove (window->priv->presentation_timeout_id); - } - - window->priv->presentation_timeout_id = 0; - - ev_view_show_cursor (EV_VIEW (window->priv->view)); -} - -static gboolean -presentation_motion_notify_cb (GtkWidget *widget, - GdkEventMotion *event, - gpointer user_data) -{ - EvWindow *window = EV_WINDOW (user_data); - - presentation_set_timeout (window); - - return FALSE; -} - -static gboolean -presentation_leave_notify_cb (GtkWidget *widget, - GdkEventCrossing *event, - gpointer user_data) -{ - EvWindow *window = EV_WINDOW (user_data); - - presentation_clear_timeout (window); - - return FALSE; -} - static void ev_window_update_presentation_action (EvWindow *window) { @@ -3489,85 +3912,92 @@ ev_window_update_presentation_action (EvWindow *window) g_signal_handlers_block_by_func (action, G_CALLBACK (ev_window_cmd_view_presentation), window); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - ev_view_get_presentation (EV_VIEW (window->priv->view))); + EV_WINDOW_IS_PRESENTATION (window)); g_signal_handlers_unblock_by_func (action, G_CALLBACK (ev_window_cmd_view_presentation), window); } +static void +ev_window_view_presentation_finished (EvWindow *window) +{ + ev_window_stop_presentation (window, TRUE); +} + static void ev_window_run_presentation (EvWindow *window) { - EvView *view = EV_VIEW (window->priv->view); gboolean fullscreen_window = TRUE; + guint current_page; + guint rotation; + gboolean inverted_colors; - if (ev_view_get_presentation (view)) + if (EV_WINDOW_IS_PRESENTATION (window)) return; - if (ev_view_get_fullscreen (view)) { + if (ev_document_model_get_fullscreen (window->priv->model)) { ev_window_stop_fullscreen (window, FALSE); fullscreen_window = FALSE; } - - g_object_set (G_OBJECT (window->priv->scrolled_window), - "shadow-type", GTK_SHADOW_NONE, - NULL); - ev_view_set_presentation (view, TRUE); - ev_window_update_presentation_action (window); + current_page = ev_document_model_get_page (window->priv->model); + rotation = ev_document_model_get_rotation (window->priv->model); + inverted_colors = ev_document_model_get_inverted_colors (window->priv->model); + window->priv->presentation_view = ev_view_presentation_new (window->priv->document, + current_page, + rotation, + inverted_colors); + g_signal_connect_swapped (window->priv->presentation_view, "finished", + G_CALLBACK (ev_window_view_presentation_finished), + window); + + gtk_box_pack_start (GTK_BOX (window->priv->main_box), + window->priv->presentation_view, + TRUE, TRUE, 0); + gtk_widget_hide (window->priv->hpaned); + ev_window_update_presentation_action (window); update_chrome_visibility (window); - - gtk_widget_grab_focus (window->priv->view); + + gtk_widget_grab_focus (window->priv->presentation_view); if (fullscreen_window) gtk_window_fullscreen (GTK_WINDOW (window)); - g_signal_connect (window->priv->view, - "motion-notify-event", - G_CALLBACK (presentation_motion_notify_cb), - window); - g_signal_connect (window->priv->view, - "leave-notify-event", - G_CALLBACK (presentation_leave_notify_cb), - window); - presentation_set_timeout (window); + gtk_widget_show (window->priv->presentation_view); ev_application_screensaver_disable (EV_APP); - - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_boolean (window->priv->uri, "presentation", TRUE); + + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "presentation", TRUE); } static void ev_window_stop_presentation (EvWindow *window, gboolean unfullscreen_window) { - EvView *view = EV_VIEW (window->priv->view); - - if (!ev_view_get_presentation (view)) + guint current_page; + + if (!EV_WINDOW_IS_PRESENTATION (window)) return; - g_object_set (G_OBJECT (window->priv->scrolled_window), - "shadow-type", GTK_SHADOW_IN, - NULL); + current_page = ev_view_presentation_get_current_page (EV_VIEW_PRESENTATION (window->priv->presentation_view)); + ev_document_model_set_page (window->priv->model, current_page); + + gtk_container_remove (GTK_CONTAINER (window->priv->main_box), + window->priv->presentation_view); + window->priv->presentation_view = NULL; - ev_view_set_presentation (EV_VIEW (window->priv->view), FALSE); + gtk_widget_show (window->priv->hpaned); ev_window_update_presentation_action (window); update_chrome_visibility (window); if (unfullscreen_window) gtk_window_unfullscreen (GTK_WINDOW (window)); - g_signal_handlers_disconnect_by_func (window->priv->view, - (gpointer) presentation_motion_notify_cb, - window); - g_signal_handlers_disconnect_by_func (window->priv->view, - (gpointer) presentation_leave_notify_cb, - window); - presentation_clear_timeout (window); + gtk_widget_grab_focus (window->priv->view); ev_application_screensaver_enable (EV_APP); - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_boolean (window->priv->uri, "presentation", FALSE); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "presentation", FALSE); } static void @@ -3610,23 +4040,47 @@ ev_window_setup_gtk_settings (EvWindow *window) g_free (menubar_accel_accel); } +static void +ev_window_update_max_min_scale (EvWindow *window) +{ + gdouble dpi; + GtkAction *action; + gdouble min_width, min_height; + gdouble width, height; + gdouble max_scale; + gint rotation = ev_document_model_get_rotation (window->priv->model); + + if (!window->priv->document) + return; + + dpi = get_screen_dpi (window) / 72.0; + + ev_document_get_min_page_size (window->priv->document, &min_width, &min_height); + width = (rotation == 0 || rotation == 180) ? min_width : min_height; + height = (rotation == 0 || rotation == 180) ? min_height : min_width; + max_scale = sqrt (PAGE_CACHE_SIZE / (width * dpi * 4 * height * dpi)); + + action = gtk_action_group_get_action (window->priv->action_group, + ZOOM_CONTROL_ACTION); + ephy_zoom_action_set_max_zoom_level (EPHY_ZOOM_ACTION (action), max_scale * dpi); + + ev_document_model_set_min_scale (window->priv->model, MIN_SCALE * dpi); + ev_document_model_set_max_scale (window->priv->model, max_scale * dpi); +} + static void ev_window_screen_changed (GtkWidget *widget, GdkScreen *old_screen) { EvWindow *window = EV_WINDOW (widget); - EvWindowPrivate *priv = window->priv; GdkScreen *screen; - gdouble dpi; screen = gtk_widget_get_screen (widget); if (screen == old_screen) return; ev_window_setup_gtk_settings (window); - dpi = get_screen_dpi (GTK_WINDOW (window)); - ev_document_model_set_min_scale (priv->model, MIN_SCALE * dpi / 72.0); - ev_document_model_set_max_scale (priv->model, MAX_SCALE * dpi / 72.0); + ev_window_update_max_min_scale (window); if (GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed) { GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed (widget, old_screen); @@ -3638,7 +4092,6 @@ ev_window_state_event (GtkWidget *widget, GdkEventWindowState *event) { EvWindow *window = EV_WINDOW (widget); - EvView *view = EV_VIEW (window->priv->view); if (GTK_WIDGET_CLASS (ev_window_parent_class)->window_state_event) { GTK_WIDGET_CLASS (ev_window_parent_class)->window_state_event (widget, event); @@ -3648,14 +4101,14 @@ ev_window_state_event (GtkWidget *widget, return FALSE; if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) { - if (ev_view_get_fullscreen (view) || ev_view_get_presentation (view)) + if (ev_document_model_get_fullscreen (window->priv->model) || EV_WINDOW_IS_PRESENTATION (window)) return FALSE; ev_window_run_fullscreen (window); } else { - if (ev_view_get_fullscreen (view)) + if (ev_document_model_get_fullscreen (window->priv->model)) ev_window_stop_fullscreen (window, FALSE); - else if (ev_view_get_presentation (view)) + else if (EV_WINDOW_IS_PRESENTATION (window)) ev_window_stop_presentation (window, FALSE); } @@ -3713,42 +4166,66 @@ ev_window_cmd_edit_rotate_right (GtkAction *action, EvWindow *ev_window) } static void -ev_window_cmd_edit_toolbar_cb (GtkDialog *dialog, gint response, gpointer data) +ev_window_cmd_view_inverted_colors (GtkAction *action, EvWindow *ev_window) { - EvWindow *ev_window = EV_WINDOW (data); - egg_editable_toolbar_set_edit_mode - (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), FALSE); - ev_application_save_toolbars_model (EV_APP); + gboolean inverted_colors = ev_document_model_get_inverted_colors (ev_window->priv->model); + + ev_document_model_set_inverted_colors (ev_window->priv->model, !inverted_colors); +} + +static void +ev_window_cmd_edit_toolbar_cb (GtkDialog *dialog, + gint response, + EvWindow *ev_window) +{ + EggEditableToolbar *toolbar; + gchar *toolbars_file; + + toolbar = EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar); + egg_editable_toolbar_set_edit_mode (toolbar, FALSE); + + toolbars_file = g_build_filename (ev_application_get_dot_dir (EV_APP, TRUE), + "evince_toolbar.xml", NULL); + egg_toolbars_model_save_toolbars (egg_editable_toolbar_get_model (toolbar), + toolbars_file, "1.0"); + g_free (toolbars_file); + gtk_widget_destroy (GTK_WIDGET (dialog)); } static void ev_window_cmd_edit_toolbar (GtkAction *action, EvWindow *ev_window) { - GtkWidget *dialog; - GtkWidget *editor; + GtkWidget *dialog; + GtkWidget *editor; + GtkWidget *content_area; + EggEditableToolbar *toolbar; dialog = gtk_dialog_new_with_buttons (_("Toolbar Editor"), - GTK_WINDOW (ev_window), - GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_WINDOW (ev_window), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, - GTK_RESPONSE_CLOSE, + GTK_RESPONSE_CLOSE, NULL); + content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)), 5); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); + gtk_box_set_spacing (GTK_BOX (content_area), 2); +#if !GTK_CHECK_VERSION (2, 90, 7) gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); +#endif gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400); - + + toolbar = EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar); editor = egg_toolbar_editor_new (ev_window->priv->ui_manager, - ev_application_get_toolbars_model (EV_APP)); + egg_editable_toolbar_get_model (toolbar)); + gtk_container_set_border_width (GTK_CONTAINER (editor), 5); gtk_box_set_spacing (GTK_BOX (EGG_TOOLBAR_EDITOR (editor)), 5); - - gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), editor); - egg_editable_toolbar_set_edit_mode - (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), TRUE); + gtk_container_add (GTK_CONTAINER (content_area), editor); + + egg_editable_toolbar_set_edit_mode (toolbar, TRUE); g_signal_connect (dialog, "response", G_CALLBACK (ev_window_cmd_edit_toolbar_cb), @@ -3756,6 +4233,34 @@ ev_window_cmd_edit_toolbar (GtkAction *action, EvWindow *ev_window) gtk_widget_show_all (dialog); } +static void +ev_window_cmd_edit_save_settings (GtkAction *action, EvWindow *ev_window) +{ + EvWindowPrivate *priv = ev_window->priv; + EvDocumentModel *model = priv->model; + GSettings *settings = priv->default_settings; + + g_settings_set_boolean (settings, "continuous", + ev_document_model_get_continuous (model)); + g_settings_set_boolean (settings, "dual-page", + ev_document_model_get_dual_page (model)); + g_settings_set_boolean (settings, "fullscreen", + ev_document_model_get_fullscreen (model)); + g_settings_set_boolean (settings, "inverted-colors", + ev_document_model_get_inverted_colors (model)); + g_settings_set_enum (settings, "sizing-mode", + ev_document_model_get_sizing_mode (model)); + g_settings_set_boolean (settings, "show-toolbar", + gtk_widget_get_visible (priv->toolbar)); + g_settings_set_boolean (settings, "show-sidebar", + gtk_widget_get_visible (priv->sidebar)); + g_settings_set_int (settings, "sidebar-size", + gtk_paned_get_position (GTK_PANED (priv->hpaned))); + g_settings_set_string (settings, "sidebar-page", + ev_window_sidebar_get_current_page_id (ev_window)); + g_settings_apply (settings); +} + static void ev_window_cmd_view_zoom_in (GtkAction *action, EvWindow *ev_window) { @@ -3848,14 +4353,20 @@ ev_window_cmd_view_autoscroll (GtkAction *action, EvWindow *ev_window) ev_view_autoscroll_start (EV_VIEW (ev_window->priv->view)); } +#if OFFLINE_HELP_ENABLED +#define EV_HELP "ghelp:evince" +#else +#define EV_HELP "http://library.gnome.org/users/evince/stable/" +#endif + static void ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window) { GError *error = NULL; gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (ev_window)), - "ghelp:evince", - GDK_CURRENT_TIME, + EV_HELP, + gtk_get_current_event_time (), &error); if (error) { ev_window_error_message (ev_window, error, @@ -3890,23 +4401,19 @@ ev_window_cmd_escape (GtkAction *action, EvWindow *window) gtk_widget_grab_focus (window->priv->view); } else { gboolean fullscreen; - gboolean presentation; - g_object_get (window->priv->view, - "fullscreen", &fullscreen, - "presentation", &presentation, - NULL); + fullscreen = ev_document_model_get_fullscreen (window->priv->model); if (fullscreen) { ev_window_stop_fullscreen (window, TRUE); - } else if (presentation) { + } else if (EV_WINDOW_IS_PRESENTATION (window)) { ev_window_stop_presentation (window, TRUE); gtk_widget_grab_focus (window->priv->view); } else { gtk_widget_grab_focus (window->priv->view); } - if (fullscreen && presentation) + if (fullscreen && EV_WINDOW_IS_PRESENTATION (window)) g_warning ("Both fullscreen and presentation set somehow"); } } @@ -3917,13 +4424,13 @@ save_sizing_mode (EvWindow *window) EvSizingMode mode; GEnumValue *enum_value; - if (ev_window_is_empty (window)) + if (!window->priv->metadata || ev_window_is_empty (window)) return; mode = ev_document_model_get_sizing_mode (window->priv->model); enum_value = g_enum_get_value (g_type_class_peek (EV_TYPE_SIZING_MODE), mode); - ev_metadata_manager_set_string (window->priv->uri, "sizing_mode", - enum_value->value_nick); + ev_metadata_set_string (window->priv->metadata, "sizing_mode", + enum_value->value_nick); } static void @@ -3958,12 +4465,15 @@ ev_window_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow * { ev_window_update_actions (ev_window); + if (!ev_window->priv->metadata) + return; + if (ev_document_model_get_sizing_mode (model) == EV_SIZING_FREE && !ev_window_is_empty (ev_window)) { gdouble zoom; zoom = ev_document_model_get_scale (model); - zoom *= 72.0 / get_screen_dpi (GTK_WINDOW(ev_window)); - ev_metadata_manager_set_double (ev_window->priv->uri, "zoom", zoom); + zoom *= 72.0 / get_screen_dpi (ev_window); + ev_metadata_set_double (ev_window->priv->metadata, "zoom", zoom); } } @@ -3976,7 +4486,7 @@ ev_window_update_continuous_action (EvWindow *window) g_signal_handlers_block_by_func (action, G_CALLBACK (ev_window_cmd_continuous), window); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - ev_view_get_continuous (EV_VIEW (window->priv->view))); + ev_document_model_get_continuous (window->priv->model)); g_signal_handlers_unblock_by_func (action, G_CALLBACK (ev_window_cmd_continuous), window); } @@ -3990,77 +4500,96 @@ ev_window_update_dual_page_action (EvWindow *window) g_signal_handlers_block_by_func (action, G_CALLBACK (ev_window_cmd_dual), window); gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - ev_view_get_dual_page (EV_VIEW (window->priv->view))); + ev_document_model_get_dual_page (window->priv->model)); g_signal_handlers_unblock_by_func (action, G_CALLBACK (ev_window_cmd_dual), window); } -static void -ev_window_continuous_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window) +static void +ev_window_continuous_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *ev_window) { ev_window_update_continuous_action (ev_window); - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_boolean (ev_window->priv->uri, "continuous", - ev_view_get_continuous (EV_VIEW (ev_window->priv->view))); + if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) + ev_metadata_set_boolean (ev_window->priv->metadata, "continuous", + ev_document_model_get_continuous (model)); } static void -ev_window_rotation_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *window) +ev_window_rotation_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *window) { gint rotation = ev_document_model_get_rotation (model); - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_int (window->priv->uri, "rotation", - rotation); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_int (window->priv->metadata, "rotation", + rotation); + + ev_window_update_max_min_scale (window); + ev_window_refresh_window_thumbnail (window); +} + +static void +ev_window_update_inverted_colors_action (EvWindow *window) +{ + GtkAction *action; - ev_window_refresh_window_thumbnail (window, rotation); + action = gtk_action_group_get_action (window->priv->action_group, "ViewInvertedColors"); + g_signal_handlers_block_by_func + (action, G_CALLBACK (ev_window_cmd_view_inverted_colors), window); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), + ev_document_model_get_inverted_colors (window->priv->model)); + g_signal_handlers_unblock_by_func + (action, G_CALLBACK (ev_window_cmd_view_inverted_colors), window); } static void -ev_window_has_selection_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *window) +ev_window_inverted_colors_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *window) { - ev_window_update_actions (window); + gboolean inverted_colors = ev_document_model_get_inverted_colors (model); + + ev_window_update_inverted_colors_action (window); + + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "inverted-colors", + inverted_colors); + + ev_window_refresh_window_thumbnail (window); } -static void -ev_window_dual_mode_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window) +static void +ev_window_dual_mode_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *ev_window) { ev_window_update_dual_page_action (ev_window); - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_boolean (ev_window->priv->uri, "dual-page", - ev_view_get_dual_page (EV_VIEW (ev_window->priv->view))); + if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) + ev_metadata_set_boolean (ev_window->priv->metadata, "dual-page", + ev_document_model_get_dual_page (model)); } static char * -build_comments_string (void) -{ -#ifdef ENABLE_PDF - PopplerBackend backend; - const char *backend_name; - const char *version; - - backend = poppler_get_backend (); - version = poppler_get_version (); - switch (backend) { - case POPPLER_BACKEND_CAIRO: - backend_name = "cairo"; - break; - case POPPLER_BACKEND_SPLASH: - backend_name = "splash"; - break; - default: - backend_name = "unknown"; - break; +build_comments_string (EvDocument *document) +{ + gchar *comments = NULL; + EvDocumentBackendInfo info; + + if (document && ev_document_get_backend_info (document, &info)) { + comments = g_strdup_printf ( + _("Document Viewer\nUsing %s (%s)"), + info.name, info.version); + } else { + comments = g_strdup_printf ( + _("Document Viewer")); } - return g_strdup_printf (_("Document Viewer.\n" - "Using poppler %s (%s)"), - version, backend_name); -#else - return g_strdup_printf (_("Document Viewer")); -#endif + return comments; } static void @@ -4094,7 +4623,7 @@ ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window) "GNU General Public License for more details.\n"), N_("You should have received a copy of the GNU General Public License " "along with Evince; if not, write to the Free Software Foundation, Inc., " - "59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n") + "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n") }; char *license_trans; @@ -4112,7 +4641,8 @@ ev_window_cmd_help_about (GtkAction *action, EvWindow *ev_window) license_trans = g_strconcat (_(license[0]), "\n", _(license[1]), "\n", _(license[2]), "\n", NULL); - comments = build_comments_string (); + + comments = build_comments_string (ev_window->priv->document); gtk_show_about_dialog ( GTK_WINDOW (ev_window), @@ -4142,46 +4672,31 @@ ev_window_view_toolbar_cb (GtkAction *action, EvWindow *ev_window) active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); update_chrome_flag (ev_window, EV_CHROME_TOOLBAR, active); update_chrome_visibility (ev_window); - ev_metadata_manager_set_boolean (NULL, "show_toolbar", active); + if (ev_window->priv->metadata) + ev_metadata_set_boolean (ev_window->priv->metadata, "show_toolbar", active); } static void ev_window_view_sidebar_cb (GtkAction *action, EvWindow *ev_window) { - if (ev_view_get_presentation (EV_VIEW (ev_window->priv->view))) + if (EV_WINDOW_IS_PRESENTATION (ev_window)) return; update_chrome_flag (ev_window, EV_CHROME_SIDEBAR, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))); update_chrome_visibility (ev_window); -} - -static void -ev_window_sidebar_current_page_changed_cb (EvSidebar *ev_sidebar, - GParamSpec *pspec, - EvWindow *ev_window) -{ - GtkWidget *current_page; - const char *id; - - g_object_get (G_OBJECT (ev_sidebar), "current_page", ¤t_page, NULL); - - if (current_page == ev_window->priv->sidebar_links) { - id = LINKS_SIDEBAR_ID; - } else if (current_page == ev_window->priv->sidebar_thumbs) { - id = THUMBNAILS_SIDEBAR_ID; - } else if (current_page == ev_window->priv->sidebar_attachments) { - id = ATTACHMENTS_SIDEBAR_ID; - } else if (current_page == ev_window->priv->sidebar_layers) { - id = LAYERS_SIDEBAR_ID; - } else { - g_assert_not_reached(); - } - - g_object_unref (current_page); +} - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_string (ev_window->priv->uri, "sidebar_page", id); +static void +ev_window_sidebar_current_page_changed_cb (EvSidebar *ev_sidebar, + GParamSpec *pspec, + EvWindow *ev_window) +{ + if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) { + ev_metadata_set_string (ev_window->priv->metadata, + "sidebar_page", + ev_window_sidebar_get_current_page_id (ev_window)); + } } static void @@ -4189,17 +4704,18 @@ ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar, GParamSpec *pspec, EvWindow *ev_window) { - EvView *view = EV_VIEW (ev_window->priv->view); GtkAction *action; action = gtk_action_group_get_action (ev_window->priv->action_group, "ViewSidebar"); - if (!ev_view_get_presentation (view)) { - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - GTK_WIDGET_VISIBLE (ev_sidebar)); + if (!EV_WINDOW_IS_PRESENTATION (ev_window)) { + gboolean visible = gtk_widget_get_visible (GTK_WIDGET (ev_sidebar)); - ev_metadata_manager_set_boolean (ev_window->priv->uri, "sidebar_visibility", - GTK_WIDGET_VISIBLE (ev_sidebar)); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), visible); + + if (ev_window->priv->metadata) + ev_metadata_set_boolean (ev_window->priv->metadata, "sidebar_visibility", + visible); } } @@ -4282,19 +4798,78 @@ view_menu_image_popup (EvWindow *ev_window, gtk_action_set_visible (action, show_image); } +static void +view_menu_annot_popup (EvWindow *ev_window, + EvAnnotation *annot) +{ + GtkAction *action; + gboolean show_annot = FALSE; + + if (ev_window->priv->annot) + g_object_unref (ev_window->priv->annot); + ev_window->priv->annot = (annot) ? g_object_ref (annot) : NULL; + + action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group, + "AnnotProperties"); + gtk_action_set_visible (action, (annot != NULL && EV_IS_ANNOTATION_MARKUP (annot))); + + if (annot && EV_IS_ANNOTATION_ATTACHMENT (annot)) { + EvAttachment *attachment; + + attachment = ev_annotation_attachment_get_attachment (EV_ANNOTATION_ATTACHMENT (annot)); + if (attachment) { + show_annot = TRUE; + if (ev_window->priv->attach_list) { + g_list_foreach (ev_window->priv->attach_list, + (GFunc) g_object_unref, NULL); + g_list_free (ev_window->priv->attach_list); + ev_window->priv->attach_list = NULL; + } + ev_window->priv->attach_list = + g_list_prepend (ev_window->priv->attach_list, + g_object_ref (attachment)); + } + } + + action = gtk_action_group_get_action (ev_window->priv->attachment_popup_action_group, + "OpenAttachment"); + gtk_action_set_visible (action, show_annot); + + action = gtk_action_group_get_action (ev_window->priv->attachment_popup_action_group, + "SaveAttachmentAs"); + gtk_action_set_visible (action, show_annot); +} + static gboolean view_menu_popup_cb (EvView *view, - GObject *object, + GList *items, EvWindow *ev_window) { - if (ev_view_get_presentation (EV_VIEW (ev_window->priv->view))) - return FALSE; + GList *l; + gboolean has_link = FALSE; + gboolean has_image = FALSE; + gboolean has_annot = FALSE; + + for (l = items; l; l = g_list_next (l)) { + if (EV_IS_LINK (l->data)) { + view_menu_link_popup (ev_window, EV_LINK (l->data)); + has_link = TRUE; + } else if (EV_IS_IMAGE (l->data)) { + view_menu_image_popup (ev_window, EV_IMAGE (l->data)); + has_image = TRUE; + } else if (EV_IS_ANNOTATION (l->data)) { + view_menu_annot_popup (ev_window, EV_ANNOTATION (l->data)); + has_annot = TRUE; + } + } + + if (!has_link) + view_menu_link_popup (ev_window, NULL); + if (!has_image) + view_menu_image_popup (ev_window, NULL); + if (!has_annot) + view_menu_annot_popup (ev_window, NULL); - view_menu_link_popup (ev_window, - EV_IS_LINK (object) ? EV_LINK (object) : NULL); - view_menu_image_popup (ev_window, - EV_IS_IMAGE (object) ? EV_IMAGE (object) : NULL); - gtk_menu_popup (GTK_MENU (ev_window->priv->view_popup), NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time ()); @@ -4336,17 +4911,23 @@ ev_window_update_find_status_message (EvWindow *ev_window) return; if (ev_job_is_finished (ev_window->priv->find_job)) { - gint n_results; - - n_results = ev_job_find_get_n_results (EV_JOB_FIND (ev_window->priv->find_job), - ev_document_model_get_page (ev_window->priv->model)); - /* TRANS: Sometimes this could be better translated as - "%d hit(s) on this page". Therefore this string - contains plural cases. */ - message = g_strdup_printf (ngettext ("%d found on this page", - "%d found on this page", - n_results), - n_results); + EvJobFind *job_find = EV_JOB_FIND (ev_window->priv->find_job); + + if (ev_job_find_has_results (job_find)) { + gint n_results; + + n_results = ev_job_find_get_n_results (job_find, + ev_document_model_get_page (ev_window->priv->model)); + /* TRANS: Sometimes this could be better translated as + "%d hit(s) on this page". Therefore this string + contains plural cases. */ + message = g_strdup_printf (ngettext ("%d found on this page", + "%d found on this page", + n_results), + n_results); + } else { + message = g_strdup (_("Not found")); + } } else { gdouble percent; @@ -4468,7 +5049,7 @@ find_bar_visibility_changed_cb (EggFindBar *find_bar, { gboolean visible; - visible = GTK_WIDGET_VISIBLE (find_bar); + visible = gtk_widget_get_visible (GTK_WIDGET (find_bar)); if (ev_window->priv->document && EV_IS_DOCUMENT_FIND (ev_window->priv->document)) { @@ -4510,7 +5091,7 @@ zoom_control_changed_cb (EphyZoomAction *action, if (mode == EV_SIZING_FREE) { ev_document_model_set_scale (ev_window->priv->model, - zoom * get_screen_dpi (GTK_WINDOW (ev_window)) / 72.0); + zoom * get_screen_dpi (ev_window) / 72.0); } } @@ -4558,15 +5139,13 @@ ev_window_drag_data_received (GtkWidget *widget, static void ev_window_finalize (GObject *object) { - GList *windows = ev_application_get_windows (EV_APP); + G_OBJECT_CLASS (ev_window_parent_class)->finalize (object); - if (windows == NULL) { + if (ev_window_n_copies == 0) { ev_application_shutdown (EV_APP); } else { - g_list_free (windows); + ev_window_n_copies--; } - - G_OBJECT_CLASS (ev_window_parent_class)->finalize (object); } static void @@ -4581,12 +5160,31 @@ ev_window_dispose (GObject *object) ev_window_media_player_key_pressed, window); } - + +#ifdef ENABLE_DBUS + if (priv->dbus_object_id > 0) { + ev_window_emit_closed (window); + g_dbus_connection_unregister_object (ev_application_get_dbus_connection (EV_APP), + priv->dbus_object_id); + priv->dbus_object_id = 0; + } + + if (priv->dbus_object_path) { + g_free (priv->dbus_object_path); + priv->dbus_object_path = NULL; + } +#endif /* ENABLE_DBUS */ + + if (priv->metadata) { + g_object_unref (priv->metadata); + priv->metadata = NULL; + } + if (priv->setup_document_idle > 0) { g_source_remove (priv->setup_document_idle); priv->setup_document_idle = 0; } - + if (priv->monitor) { g_object_unref (priv->monitor); priv->monitor = NULL; @@ -4629,6 +5227,22 @@ ev_window_dispose (GObject *object) priv->recent_manager = NULL; } + if (priv->settings) { + g_object_unref (priv->settings); + priv->settings = NULL; + } + + if (priv->default_settings) { + g_settings_apply (priv->default_settings); + g_object_unref (priv->default_settings); + priv->default_settings = NULL; + } + + if (priv->lockdown_settings) { + g_object_unref (priv->lockdown_settings); + priv->lockdown_settings = NULL; + } + priv->recent_ui_id = 0; if (priv->model) { @@ -4687,16 +5301,6 @@ ev_window_dispose (GObject *object) ev_window_close_dialogs (window); - if (window->priv->print_settings) { - g_object_unref (window->priv->print_settings); - window->priv->print_settings = NULL; - } - - if (window->priv->print_page_setup) { - g_object_unref (window->priv->print_page_setup); - window->priv->print_page_setup = NULL; - } - if (priv->link) { g_object_unref (priv->link); priv->link = NULL; @@ -4707,6 +5311,11 @@ ev_window_dispose (GObject *object) priv->image = NULL; } + if (priv->annot) { + g_object_unref (priv->annot); + priv->annot = NULL; + } + if (priv->attach_list) { g_list_foreach (priv->attach_list, (GFunc) g_object_unref, @@ -4743,11 +5352,6 @@ ev_window_dispose (GObject *object) priv->history = NULL; } - if (priv->presentation_timeout_id > 0) { - g_source_remove (priv->presentation_timeout_id); - priv->presentation_timeout_id = 0; - } - if (priv->print_queue) { g_queue_free (priv->print_queue); priv->print_queue = NULL; @@ -4783,18 +5387,18 @@ ev_window_key_press_event (GtkWidget *widget, */ if (priv->view) { g_object_ref (priv->view); - if (GTK_WIDGET_IS_SENSITIVE (priv->view)) + if (gtk_widget_is_sensitive (priv->view)) handled = gtk_widget_event (priv->view, (GdkEvent*) event); g_object_unref (priv->view); } - if (!handled && !ev_view_get_presentation (EV_VIEW (priv->view))) { + if (!handled && !EV_WINDOW_IS_PRESENTATION (ev_window)) { guint modifier = event->state & gtk_accelerator_get_default_mod_mask (); if (priv->menubar_accel_keyval != 0 && event->keyval == priv->menubar_accel_keyval && modifier == priv->menubar_accel_modifier) { - if (!GTK_WIDGET_VISIBLE (priv->menubar)) { + if (!gtk_widget_get_visible (priv->menubar)) { g_signal_connect (priv->menubar, "deactivate", G_CALLBACK (menubar_deactivate_cb), ev_window); @@ -4814,6 +5418,13 @@ ev_window_key_press_event (GtkWidget *widget, return handled; } +static gboolean +ev_window_delete_event (GtkWidget *widget, + GdkEventAny *event) +{ + return !ev_window_close (EV_WINDOW (widget)); +} + static void ev_window_class_init (EvWindowClass *ev_window_class) { @@ -4823,6 +5434,7 @@ ev_window_class_init (EvWindowClass *ev_window_class) g_object_class->dispose = ev_window_dispose; g_object_class->finalize = ev_window_finalize; + widget_class->delete_event = ev_window_delete_event; widget_class->key_press_event = ev_window_key_press_event; widget_class->screen_changed = ev_window_screen_changed; widget_class->window_state_event = ev_window_state_event; @@ -4840,19 +5452,19 @@ static const GtkActionEntry entries[] = { { "Help", NULL, N_("_Help") }, /* File menu */ - { "FileOpen", GTK_STOCK_OPEN, N_("_Open..."), "O", + { "FileOpen", GTK_STOCK_OPEN, N_("_Open…"), "O", N_("Open an existing document"), G_CALLBACK (ev_window_cmd_file_open) }, { "FileOpenCopy", NULL, N_("Op_en a Copy"), "N", N_("Open a copy of the current document in a new window"), G_CALLBACK (ev_window_cmd_file_open_copy) }, - { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), "S", + { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy…"), "S", N_("Save a copy of the current document"), G_CALLBACK (ev_window_cmd_save_as) }, - { "FilePageSetup", GTK_STOCK_PAGE_SETUP, N_("Page Set_up..."), NULL, - N_("Setup the page settings for printing"), - G_CALLBACK (ev_window_cmd_file_print_setup) }, - { "FilePrint", GTK_STOCK_PRINT, N_("_Print..."), "P", + { "FileOpenContainingFolder", GTK_STOCK_DIRECTORY, N_("Open Containing _Folder"), NULL, + N_("Show the folder which contains this file in the file manager"), + G_CALLBACK (ev_window_cmd_open_containing_folder) }, + { "FilePrint", GTK_STOCK_PRINT, N_("_Print…"), "P", N_("Print this document"), G_CALLBACK (ev_window_cmd_file_print) }, { "FileProperties", GTK_STOCK_PROPERTIES, N_("P_roperties"), "Return", NULL, @@ -4865,7 +5477,7 @@ static const GtkActionEntry entries[] = { G_CALLBACK (ev_window_cmd_edit_copy) }, { "EditSelectAll", GTK_STOCK_SELECT_ALL, N_("Select _All"), "A", NULL, G_CALLBACK (ev_window_cmd_edit_select_all) }, - { "EditFind", GTK_STOCK_FIND, N_("_Find..."), "F", + { "EditFind", GTK_STOCK_FIND, N_("_Find…"), "F", N_("Find a word or phrase in the document"), G_CALLBACK (ev_window_cmd_edit_find) }, { "EditFindNext", NULL, N_("Find Ne_xt"), "G", NULL, @@ -4878,6 +5490,9 @@ static const GtkActionEntry entries[] = { G_CALLBACK (ev_window_cmd_edit_rotate_left) }, { "EditRotateRight", EV_STOCK_ROTATE_RIGHT, N_("Rotate _Right"), "Right", NULL, G_CALLBACK (ev_window_cmd_edit_rotate_right) }, + { "EditSaveSettings", NULL, N_("Save Current Settings as _Default"), "T", NULL, + G_CALLBACK (ev_window_cmd_edit_save_settings) }, + /* View menu */ { "ViewZoomIn", GTK_STOCK_ZOOM_IN, NULL, "plus", @@ -4945,6 +5560,10 @@ static const GtkActionEntry entries[] = { G_CALLBACK (ev_window_cmd_scroll_forward) }, { "ShiftReturn", NULL, "", "Return", NULL, G_CALLBACK (ev_window_cmd_scroll_backward) }, + { "p", GTK_STOCK_GO_UP, "", "p", NULL, + G_CALLBACK (ev_window_cmd_go_previous_page) }, + { "n", GTK_STOCK_GO_DOWN, "", "n", NULL, + G_CALLBACK (ev_window_cmd_go_next_page) }, { "Plus", GTK_STOCK_ZOOM_IN, NULL, "plus", NULL, G_CALLBACK (ev_window_cmd_view_zoom_in) }, { "CtrlEqual", GTK_STOCK_ZOOM_IN, NULL, "equal", NULL, @@ -4998,6 +5617,10 @@ static const GtkToggleActionEntry toggle_entries[] = { { "ViewPageWidth", EV_STOCK_ZOOM_WIDTH, N_("Fit Page _Width"), NULL, N_("Make the current document fill the window width"), G_CALLBACK (ev_window_cmd_view_page_width) }, + { "ViewInvertedColors", EV_STOCK_INVERTED_COLORS, N_("_Inverted Colors"), "I", + N_("Show page contents with the colors inverted"), + G_CALLBACK (ev_window_cmd_view_inverted_colors) }, + }; /* Popups specific items */ @@ -5011,16 +5634,18 @@ static const GtkActionEntry view_popup_entries [] = { NULL, G_CALLBACK (ev_view_popup_cmd_open_link_new_window) }, { "CopyLinkAddress", NULL, N_("_Copy Link Address"), NULL, NULL, G_CALLBACK (ev_view_popup_cmd_copy_link_address) }, - { "SaveImageAs", NULL, N_("_Save Image As..."), NULL, + { "SaveImageAs", NULL, N_("_Save Image As…"), NULL, NULL, G_CALLBACK (ev_view_popup_cmd_save_image_as) }, { "CopyImage", NULL, N_("Copy _Image"), NULL, NULL, G_CALLBACK (ev_view_popup_cmd_copy_image) }, + { "AnnotProperties", NULL, N_("Annotation Properties…"), NULL, + NULL, G_CALLBACK (ev_view_popup_cmd_annot_properties) } }; static const GtkActionEntry attachment_popup_entries [] = { - { "OpenAttachment", GTK_STOCK_OPEN, N_("_Open..."), NULL, + { "OpenAttachment", GTK_STOCK_OPEN, N_("_Open Attachment"), NULL, NULL, G_CALLBACK (ev_attachment_popup_cmd_open_attachment) }, - { "SaveAttachmentAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), NULL, + { "SaveAttachmentAs", GTK_STOCK_SAVE_AS, N_("_Save Attachment As…"), NULL, NULL, G_CALLBACK (ev_attachment_popup_cmd_save_attachment_as) }, }; @@ -5052,6 +5677,38 @@ sidebar_layers_visibility_changed (EvSidebarLayers *layers, ev_view_reload (EV_VIEW (window->priv->view)); } +static void +sidebar_annots_annot_activated_cb (EvSidebarAnnotations *sidebar_annots, + EvMapping *annot_mapping, + EvWindow *window) +{ + ev_view_focus_annotation (EV_VIEW (window->priv->view), annot_mapping); +} + +static void +sidebar_annots_begin_annot_add (EvSidebarAnnotations *sidebar_annots, + EvAnnotationType annot_type, + EvWindow *window) +{ + ev_view_begin_add_annotation (EV_VIEW (window->priv->view), annot_type); +} + +static void +view_annot_added (EvView *view, + EvAnnotation *annot, + EvWindow *window) +{ + ev_sidebar_annotations_annot_added (EV_SIDEBAR_ANNOTATIONS (window->priv->sidebar_annots), + annot); +} + +static void +sidebar_annots_annot_add_cancelled (EvSidebarAnnotations *sidebar_annots, + EvWindow *window) +{ + ev_view_cancel_add_annotation (EV_VIEW (window->priv->view)); +} + static void register_custom_actions (EvWindow *window, GtkActionGroup *group) { @@ -5099,7 +5756,7 @@ register_custom_actions (EvWindow *window, GtkActionGroup *group) action = g_object_new (EV_TYPE_OPEN_RECENT_ACTION, "name", "FileOpenRecent", - "label", _("_Open..."), + "label", _("_Open…"), "tooltip", _("Open an existing document"), "stock_id", GTK_STOCK_OPEN, NULL); @@ -5117,6 +5774,10 @@ set_action_properties (GtkActionGroup *action_group) { GtkAction *action; + action = gtk_action_group_get_action (action_group, "FileOpenContainingFolder"); + /*translators: this is the label for toolbar button*/ + g_object_set (action, "short_label", _("Open Folder"), NULL); + action = gtk_action_group_get_action (action_group, "GoPreviousPage"); g_object_set (action, "is-important", TRUE, NULL); /*translators: this is the label for toolbar button*/ @@ -5147,22 +5808,6 @@ set_action_properties (GtkActionGroup *action_group) g_object_set (action, "is-important", TRUE, NULL); } -static void -set_chrome_actions (EvWindow *window) -{ - EvWindowPrivate *priv = window->priv; - GtkActionGroup *action_group = priv->action_group; - GtkAction *action; - - action= gtk_action_group_get_action (action_group, "ViewToolbar"); - g_signal_handlers_block_by_func - (action, G_CALLBACK (ev_window_view_toolbar_cb), window); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - (priv->chrome & EV_CHROME_TOOLBAR) != 0); - g_signal_handlers_unblock_by_func - (action, G_CALLBACK (ev_window_view_toolbar_cb), window); -} - static void sidebar_widget_model_set (EvSidebarLinks *ev_sidebar_links, GParamSpec *pspec, @@ -5235,8 +5880,8 @@ window_state_event_cb (EvWindow *window, GdkEventWindowState *event, gpointer du gboolean maximized; maximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED; - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_boolean (window->priv->uri, "window_maximized", maximized); + if (window->priv->metadata && !ev_window_is_empty (window)) + ev_metadata_set_boolean (window->priv->metadata, "window_maximized", maximized); } return FALSE; @@ -5245,25 +5890,26 @@ window_state_event_cb (EvWindow *window, GdkEventWindowState *event, gpointer du static gboolean window_configure_event_cb (EvWindow *window, GdkEventConfigure *event, gpointer dummy) { - char *uri = window->priv->uri; GdkWindowState state; gdouble document_width, document_height; - state = gdk_window_get_state (GTK_WIDGET (window)->window); + if (!window->priv->metadata) + return FALSE; + + state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (window))); if (!(state & GDK_WINDOW_STATE_FULLSCREEN)) { - if (!ev_window_is_empty (window) && window->priv->document) { + if (window->priv->document) { ev_document_get_max_page_size (window->priv->document, &document_width, &document_height); - ev_metadata_manager_set_double (uri, "window_width_ratio", - (double)event->width / document_width); - ev_metadata_manager_set_double (uri, "window_height_ratio", - (double)event->height / document_height); - - ev_metadata_manager_set_int (uri, "window_x", event->x); - ev_metadata_manager_set_int (uri, "window_y", event->y); - ev_metadata_manager_set_int (uri, "window_width", event->width); - ev_metadata_manager_set_int (uri, "window_height", event->height); + g_settings_set (window->priv->default_settings, "window-ratio", "(dd)", + (double)event->width / document_width, + (double)event->height / document_height); + + ev_metadata_set_int (window->priv->metadata, "window_x", event->x); + ev_metadata_set_int (window->priv->metadata, "window_y", event->y); + ev_metadata_set_int (window->priv->metadata, "window_width", event->width); + ev_metadata_set_int (window->priv->metadata, "window_height", event->height); } } @@ -5311,7 +5957,8 @@ launch_action (EvWindow *window, EvLinkAction *action) context = G_APP_LAUNCH_CONTEXT (gdk_app_launch_context_new ()); gdk_app_launch_context_set_screen (GDK_APP_LAUNCH_CONTEXT (context), gtk_window_get_screen (GTK_WINDOW (window))); - gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context), GDK_CURRENT_TIME); + gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context), + gtk_get_current_event_time ()); file_list.data = file; if (!g_app_info_launch (app_info, &file_list, context, &error)) { @@ -5323,6 +5970,7 @@ launch_action (EvWindow *window, EvLinkAction *action) g_object_unref (app_info); g_object_unref (file); + /* FIXMEchpe: unref launch context? */ /* According to the PDF spec filename can be an executable. I'm not sure allowing to launch executables is a good idea though. -- marco */ @@ -5340,25 +5988,44 @@ launch_external_uri (EvWindow *window, EvLinkAction *action) gdk_app_launch_context_set_screen (GDK_APP_LAUNCH_CONTEXT (context), gtk_window_get_screen (GTK_WINDOW (window))); gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context), - GDK_CURRENT_TIME); + gtk_get_current_event_time ()); if (!g_strstr_len (uri, strlen (uri), "://") && !g_str_has_prefix (uri, "mailto:")) { - gchar *http; - - /* Not a valid uri, assuming it's http */ - http = g_strdup_printf ("http://%s", uri); - ret = g_app_info_launch_default_for_uri (http, NULL, &error); - g_free (http); + gchar *new_uri; + + /* Not a valid uri, assume http if it starts with www */ + if (g_str_has_prefix (uri, "www.")) { + new_uri = g_strdup_printf ("http://%s", uri); + } else { + GFile *file, *parent; + + file = g_file_new_for_uri (window->priv->uri); + parent = g_file_get_parent (file); + g_object_unref (file); + if (parent) { + gchar *parent_uri = g_file_get_uri (parent); + + new_uri = g_build_filename (parent_uri, uri, NULL); + g_free (parent_uri); + g_object_unref (parent); + } else { + new_uri = g_strdup_printf ("file:///%s", uri); + } + } + ret = g_app_info_launch_default_for_uri (new_uri, context, &error); + g_free (new_uri); } else { - ret = g_app_info_launch_default_for_uri (uri, NULL, &error); + ret = g_app_info_launch_default_for_uri (uri, context, &error); } - + if (ret == FALSE) { - ev_window_error_message (window, error, + ev_window_error_message (window, error, "%s", _("Unable to open external link")); g_error_free (error); } + + /* FIXMEchpe: unref launch context? */ } static void @@ -5378,7 +6045,7 @@ open_remote_link (EvWindow *window, EvLinkAction *action) ev_link_action_get_dest (action), 0, NULL, - GDK_CURRENT_TIME); + gtk_get_current_event_time ()); g_free (uri); } @@ -5545,7 +6212,9 @@ image_save_dialog_response_cb (GtkWidget *fc, if (is_native) { filename = g_file_get_path (target_file); } else { - filename = ev_tmp_filename ("saveimage"); + /* Create a temporary local file to save to */ + if (ev_mkstemp ("saveimage.XXXXXX", &filename, &error) == -1) + goto has_error; } ev_document_doc_mutex_lock (); @@ -5558,6 +6227,7 @@ image_save_dialog_response_cb (GtkWidget *fc, g_free (file_format); g_object_unref (pixbuf); + has_error: if (error) { ev_window_error_message (ev_window, error, "%s", _("The image could not be saved.")); @@ -5638,6 +6308,67 @@ ev_view_popup_cmd_copy_image (GtkAction *action, EvWindow *window) g_object_unref (pixbuf); } +static void +ev_view_popup_cmd_annot_properties (GtkAction *action, + EvWindow *window) +{ + const gchar *author; + GdkColor color; + gdouble opacity; + gboolean popup_is_open; + EvAnnotationPropertiesDialog *dialog; + EvAnnotation *annot = window->priv->annot; + EvAnnotationsSaveMask mask = EV_ANNOTATIONS_SAVE_NONE; + + if (!annot) + return; + + dialog = EV_ANNOTATION_PROPERTIES_DIALOG (ev_annotation_properties_dialog_new_with_annotation (window->priv->annot)); + if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_APPLY) { + gtk_widget_destroy (GTK_WIDGET (dialog)); + + return; + } + + /* Set annotations changes */ + author = ev_annotation_properties_dialog_get_author (dialog); + if (ev_annotation_markup_set_label (EV_ANNOTATION_MARKUP (annot), author)) + mask |= EV_ANNOTATIONS_SAVE_LABEL; + + ev_annotation_properties_dialog_get_color (dialog, &color); + if (ev_annotation_set_color (annot, &color)) + mask |= EV_ANNOTATIONS_SAVE_COLOR; + + opacity = ev_annotation_properties_dialog_get_opacity (dialog); + if (ev_annotation_markup_set_opacity (EV_ANNOTATION_MARKUP (annot), opacity)) + mask |= EV_ANNOTATIONS_SAVE_OPACITY; + + popup_is_open = ev_annotation_properties_dialog_get_popup_is_open (dialog); + if (ev_annotation_markup_set_popup_is_open (EV_ANNOTATION_MARKUP (annot), popup_is_open)) + mask |= EV_ANNOTATIONS_SAVE_POPUP_IS_OPEN; + + if (EV_IS_ANNOTATION_TEXT (annot)) { + EvAnnotationTextIcon icon; + + icon = ev_annotation_properties_dialog_get_text_icon (dialog); + if (ev_annotation_text_set_icon (EV_ANNOTATION_TEXT (annot), icon)) + mask |= EV_ANNOTATIONS_SAVE_TEXT_ICON; + } + + if (mask != EV_ANNOTATIONS_SAVE_NONE) { + ev_document_doc_mutex_lock (); + ev_document_annotations_save_annotation (EV_DOCUMENT_ANNOTATIONS (window->priv->document), + window->priv->annot, + mask); + ev_document_doc_mutex_unlock (); + + /* FIXME: update annot region only */ + ev_view_reload (EV_VIEW (window->priv->view)); + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); +} + static void ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window) { @@ -5655,7 +6386,7 @@ ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window) attachment = (EvAttachment *) l->data; - ev_attachment_open (attachment, screen, GDK_CURRENT_TIME, &error); + ev_attachment_open (attachment, screen, gtk_get_current_event_time (), &error); if (error) { ev_window_error_message (window, error, @@ -5690,7 +6421,7 @@ attachment_save_dialog_response_cb (GtkWidget *fc, for (l = ev_window->priv->attach_list; l && l->data; l = g_list_next (l)) { EvAttachment *attachment; - GFile *save_to; + GFile *save_to = NULL; GError *error = NULL; attachment = (EvAttachment *) l->data; @@ -5698,15 +6429,17 @@ attachment_save_dialog_response_cb (GtkWidget *fc, if (is_native) { if (is_dir) { save_to = g_file_get_child (target_file, + /* FIXMEchpe: file name encoding! */ ev_attachment_get_name (attachment)); } else { save_to = g_object_ref (target_file); } } else { - save_to = ev_tmp_file_get ("saveattachment"); + save_to = ev_mkstemp_file ("saveattachment.XXXXXX", &error); } - ev_attachment_save (attachment, save_to, &error); + if (save_to) + ev_attachment_save (attachment, save_to, &error); if (error) { ev_window_error_message (ev_window, error, @@ -5812,6 +6545,203 @@ ev_window_media_player_key_pressed (EvWindow *window, } } +static EggToolbarsModel * +get_toolbars_model (void) +{ + EggToolbarsModel *toolbars_model; + gchar *toolbars_file; + gchar *toolbars_path; + gint i; + + toolbars_model = egg_toolbars_model_new (); + + toolbars_file = g_build_filename (ev_application_get_dot_dir (EV_APP, FALSE), + "evince_toolbar.xml", NULL); + toolbars_path = g_build_filename (ev_application_get_data_dir (EV_APP), + "evince-toolbar.xml", NULL); + egg_toolbars_model_load_names (toolbars_model, toolbars_path); + + if (!egg_toolbars_model_load_toolbars (toolbars_model, toolbars_file)) { + egg_toolbars_model_load_toolbars (toolbars_model, toolbars_path); + goto skip_conversion; + } + + /* Open item doesn't exist anymore, + * convert it to OpenRecent for compatibility + */ + for (i = 0; i < egg_toolbars_model_n_items (toolbars_model, 0); i++) { + const gchar *item; + + item = egg_toolbars_model_item_nth (toolbars_model, 0, i); + if (g_ascii_strcasecmp (item, "FileOpen") == 0) { + egg_toolbars_model_remove_item (toolbars_model, 0, i); + egg_toolbars_model_add_item (toolbars_model, 0, i, + "FileOpenRecent"); + egg_toolbars_model_save_toolbars (toolbars_model, toolbars_file, "1.0"); + break; + } + } + + skip_conversion: + g_free (toolbars_file); + g_free (toolbars_path); + + egg_toolbars_model_set_flags (toolbars_model, 0, EGG_TB_MODEL_NOT_REMOVABLE); + + return toolbars_model; +} + +#ifdef ENABLE_DBUS +static void +ev_window_sync_source (EvWindow *window, + EvSourceLink *link) +{ + GDBusConnection *connection; + GError *error = NULL; + + if (window->priv->dbus_object_id <= 0) + return; + + connection = ev_application_get_dbus_connection (EV_APP); + if (!connection) + return; + + g_dbus_connection_emit_signal (connection, + NULL, + window->priv->dbus_object_path, + EV_WINDOW_DBUS_INTERFACE, + "SyncSource", + g_variant_new ("(s(ii))", + link->filename, + link->line, + link->col), + &error); + if (error) { + g_printerr ("Failed to emit DBus signal SyncSource: %s\n", + error->message); + g_error_free (error); + } +} + +static void +ev_window_emit_closed (EvWindow *window) +{ + GDBusConnection *connection; + GError *error = NULL; + + if (window->priv->dbus_object_id <= 0) + return; + + connection = ev_application_get_dbus_connection (EV_APP); + if (!connection) + return; + + g_dbus_connection_emit_signal (connection, + NULL, + window->priv->dbus_object_path, + EV_WINDOW_DBUS_INTERFACE, + "Closed", + NULL, + &error); + if (error) { + g_printerr ("Failed to emit DBus signal Closed: %s\n", + error->message); + g_error_free (error); + + return; + } + + /* If this is the last window call g_dbus_connection_flush_sync() + * to make sure the signal is emitted. + */ + if (ev_application_get_n_windows (EV_APP) == 1) + g_dbus_connection_flush_sync (connection, NULL, NULL); +} + +static void +ev_window_emit_doc_loaded (EvWindow *window) +{ + GDBusConnection *connection; + GError *error = NULL; + + if (window->priv->dbus_object_id <= 0) + return; + + connection = ev_application_get_dbus_connection (EV_APP); + if (!connection) + return; + + g_dbus_connection_emit_signal (connection, + NULL, + window->priv->dbus_object_path, + EV_WINDOW_DBUS_INTERFACE, + "DocumentLoaded", + g_variant_new("(s)", window->priv->uri), + &error); + if (error) { + g_printerr ("Failed to emit DBus signal DocumentLoaded: %s\n", + error->message); + g_error_free (error); + + return; + } +} + +static void +method_call_cb (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + EvWindow *window = EV_WINDOW (user_data); + + if (g_strcmp0 (method_name, "SyncView") != 0) + return; + + if (window->priv->document && ev_document_has_synctex (window->priv->document)) { + EvSourceLink link; + guint32 timestamp; + + g_variant_get (parameters, "(&s(ii)u)", &link.filename, &link.line, &link.col, ×tamp); + ev_view_highlight_forward_search (EV_VIEW (window->priv->view), &link); + gtk_window_present_with_time (GTK_WINDOW (window), timestamp); + } + + g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); +} + +static const char introspection_xml[] = + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + +static const GDBusInterfaceVTable interface_vtable = { + method_call_cb, + NULL, + NULL +}; + +static GDBusNodeInfo *introspection_data; +#endif /* ENABLE_DBUS */ + static void ev_window_init (EvWindow *ev_window) { @@ -5819,9 +6749,14 @@ ev_window_init (EvWindow *ev_window) GtkAccelGroup *accel_group; GError *error = NULL; GtkWidget *sidebar_widget; + GtkWidget *menuitem; + EggToolbarsModel *toolbars_model; GObject *mpkeys; gchar *ui_path; - gdouble dpi; +#ifdef ENABLE_DBUS + GDBusConnection *connection; + static gint window_id = 0; +#endif g_signal_connect (ev_window, "configure_event", G_CALLBACK (window_configure_event_cb), NULL); @@ -5830,6 +6765,35 @@ ev_window_init (EvWindow *ev_window) ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window); +#ifdef ENABLE_DBUS + connection = ev_application_get_dbus_connection (EV_APP); + if (connection) { + if (!introspection_data) { + introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, &error); + if (error) g_warning ("%s\n", error->message); + } + g_assert (introspection_data != NULL); + + ev_window->priv->dbus_object_path = g_strdup_printf (EV_WINDOW_DBUS_OBJECT_PATH, window_id++); + ev_window->priv->dbus_object_id = + g_dbus_connection_register_object (connection, + ev_window->priv->dbus_object_path, + introspection_data->interfaces[0], + &interface_vtable, + ev_window, NULL, + &error); + if (ev_window->priv->dbus_object_id == 0) { + g_printerr ("Failed to register bus object %s: %s\n", + ev_window->priv->dbus_object_path, error->message); + g_error_free (error); + g_free (ev_window->priv->dbus_object_path); + ev_window->priv->dbus_object_path = NULL; + error = NULL; + } + } + +#endif /* ENABLE_DBUS */ + ev_window->priv->model = ev_document_model_new (); ev_window->priv->page_mode = PAGE_MODE_DOCUMENT; @@ -5887,7 +6851,7 @@ ev_window_init (EvWindow *ev_window) g_error_free (error); } g_free (ui_path); - + ev_window->priv->recent_manager = gtk_recent_manager_get_default (); ev_window->priv->recent_action_group = NULL; ev_window->priv->recent_ui_id = 0; @@ -5902,13 +6866,21 @@ ev_window_init (EvWindow *ev_window) gtk_box_pack_start (GTK_BOX (ev_window->priv->main_box), ev_window->priv->menubar, FALSE, FALSE, 0); - - ev_window->priv->toolbar = GTK_WIDGET - (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR, - "ui-manager", ev_window->priv->ui_manager, - "popup-path", "/ToolbarPopup", - "model", ev_application_get_toolbars_model (EV_APP), - NULL)); + menuitem = gtk_ui_manager_get_widget (ev_window->priv->ui_manager, + "/MainMenu/EditMenu/EditRotateLeftMenu"); + gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE); + menuitem = gtk_ui_manager_get_widget (ev_window->priv->ui_manager, + "/MainMenu/EditMenu/EditRotateRightMenu"); + gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE); + + toolbars_model = get_toolbars_model (); + ev_window->priv->toolbar = GTK_WIDGET + (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR, + "ui-manager", ev_window->priv->ui_manager, + "popup-path", "/ToolbarPopup", + "model", toolbars_model, + NULL)); + g_object_unref (toolbars_model); egg_editable_toolbar_show (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), "DefaultToolBar"); @@ -5984,6 +6956,24 @@ ev_window_init (EvWindow *ev_window) ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar), sidebar_widget); + sidebar_widget = ev_sidebar_annotations_new (); + ev_window->priv->sidebar_annots = sidebar_widget; + g_signal_connect (sidebar_widget, + "annot_activated", + G_CALLBACK (sidebar_annots_annot_activated_cb), + ev_window); + g_signal_connect (sidebar_widget, + "begin_annot_add", + G_CALLBACK (sidebar_annots_begin_annot_add), + ev_window); + g_signal_connect (sidebar_widget, + "annot_add_cancelled", + G_CALLBACK (sidebar_annots_annot_add_cancelled), + ev_window); + gtk_widget_show (sidebar_widget); + ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar), + sidebar_widget); + ev_window->priv->view_box = gtk_vbox_new (FALSE, 0); ev_window->priv->scrolled_window = GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW, @@ -5999,12 +6989,9 @@ ev_window_init (EvWindow *ev_window) gtk_widget_show (ev_window->priv->view_box); ev_window->priv->view = ev_view_new (); + ev_view_set_page_cache_size (EV_VIEW (ev_window->priv->view), PAGE_CACHE_SIZE); ev_view_set_model (EV_VIEW (ev_window->priv->view), ev_window->priv->model); - dpi = get_screen_dpi (GTK_WINDOW (ev_window)); - ev_document_model_set_min_scale (ev_window->priv->model, MIN_SCALE * dpi / 72.0); - ev_document_model_set_max_scale (ev_window->priv->model, MAX_SCALE * dpi / 72.0); - ev_view_set_screen_dpi (EV_VIEW (ev_window->priv->view), - get_screen_dpi (GTK_WINDOW (ev_window))); + ev_window->priv->password_view = ev_password_view_new (GTK_WINDOW (ev_window)); g_signal_connect_swapped (ev_window->priv->password_view, "unlock", @@ -6022,10 +7009,23 @@ ev_window_init (EvWindow *ev_window) g_signal_connect_object (ev_window->priv->view, "handle-link", G_CALLBACK (view_handle_link_cb), ev_window, 0); - g_signal_connect_object (ev_window->priv->view, - "popup", + g_signal_connect_object (ev_window->priv->view, "popup", G_CALLBACK (view_menu_popup_cb), ev_window, 0); + g_signal_connect_object (ev_window->priv->view, "selection-changed", + G_CALLBACK (view_selection_changed_cb), + ev_window, 0); + g_signal_connect_object (ev_window->priv->view, "annot-added", + G_CALLBACK (view_annot_added), + ev_window, 0); + g_signal_connect_object (ev_window->priv->view, "layers-changed", + G_CALLBACK (view_layers_changed_cb), + ev_window, 0); +#ifdef ENABLE_DBUS + g_signal_connect_swapped (ev_window->priv->view, "sync-source", + G_CALLBACK (ev_window_sync_source), + ev_window); +#endif gtk_widget_show (ev_window->priv->view); gtk_widget_show (ev_window->priv->password_view); @@ -6063,19 +7063,17 @@ ev_window_init (EvWindow *ev_window) "notify::rotation", G_CALLBACK (ev_window_rotation_changed_cb), ev_window); - - /* Connect to view signals */ - g_signal_connect (ev_window->priv->view, - "notify::dual-page", - G_CALLBACK (ev_window_dual_mode_changed_cb), - ev_window); - g_signal_connect (ev_window->priv->view, + g_signal_connect (ev_window->priv->model, "notify::continuous", G_CALLBACK (ev_window_continuous_changed_cb), ev_window); - g_signal_connect (ev_window->priv->view, - "notify::has-selection", - G_CALLBACK (ev_window_has_selection_changed_cb), + g_signal_connect (ev_window->priv->model, + "notify::dual-page", + G_CALLBACK (ev_window_dual_mode_changed_cb), + ev_window); + g_signal_connect (ev_window->priv->model, + "notify::inverted-colors", + G_CALLBACK (ev_window_inverted_colors_changed_cb), ev_window); /* Connect sidebar signals */ @@ -6138,13 +7136,16 @@ ev_window_init (EvWindow *ev_window) /* Give focus to the document view */ gtk_widget_grab_focus (ev_window->priv->view); + ev_window->priv->default_settings = g_settings_new (GS_SCHEMA_NAME".Default"); + g_settings_delay (ev_window->priv->default_settings); + /* Set it user interface params */ ev_window_setup_recent (ev_window); ev_window_setup_gtk_settings (ev_window); setup_chrome_from_metadata (ev_window); - set_chrome_actions (ev_window); + update_chrome_actions (ev_window); update_chrome_visibility (ev_window); gtk_window_set_default_size (GTK_WINDOW (ev_window), 600, 600); @@ -6181,3 +7182,13 @@ ev_window_new (void) return ev_window; } + +const gchar * +ev_window_get_dbus_object_path (EvWindow *ev_window) +{ +#ifdef ENABLE_DBUS + return ev_window->priv->dbus_object_path; +#else + return NULL; +#endif +}