X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-window.c;h=89d18d997863c792ca245cf7ebd2140f681f0b63;hb=8c953cdc1375d46bd4fcc9341ec263b6b2eedad8;hp=d4134f4316df921263d50ec3b4136b9f4b630aa4;hpb=4cc59b9954bbf8728cbdb33cff772c8c4edcbe89;p=evince.git diff --git a/shell/ev-window.c b/shell/ev-window.c index d4134f43..89d18d99 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -34,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" @@ -59,7 +56,6 @@ #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" @@ -77,6 +73,7 @@ #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" @@ -93,6 +90,7 @@ #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" @@ -139,10 +137,12 @@ struct _EvWindowPrivate { GtkWidget *sidebar_links; GtkWidget *sidebar_attachments; GtkWidget *sidebar_layers; + GtkWidget *sidebar_annots; /* Settings */ GSettings *settings; - GSettings *last_settings; + GSettings *default_settings; + GSettings *lockdown_settings; /* Menubar accels */ guint menubar_accel_keyval; @@ -169,9 +169,10 @@ struct _EvWindowPrivate { GtkWidget *fullscreen_toolbar; /* Popup view */ - GtkWidget *view_popup; - EvLink *link; - EvImage *image; + GtkWidget *view_popup; + EvLink *link; + EvImage *image; + EvAnnotation *annot; /* Popup attachment */ GtkWidget *attachment_popup; @@ -191,6 +192,7 @@ struct _EvWindowPrivate { EvWindowPageMode page_mode; EvWindowTitle *title; EvMetadata *metadata; + gboolean is_new_doc; /* Load params */ EvLinkDest *dest; @@ -208,8 +210,11 @@ struct _EvWindowPrivate { GtkPrintSettings *print_settings; GtkPageSetup *print_page_setup; gboolean close_after_print; -#ifdef WITH_GCONF - GConfClient *gconf_client; + +#ifdef ENABLE_DBUS + /* DBus */ + guint dbus_object_id; + gchar *dbus_object_path; #endif }; @@ -222,20 +227,25 @@ struct _EvWindowPrivate { #define ZOOM_CONTROL_ACTION "ViewZoom" #define NAVIGATION_ACTION "Navigation" -#define GCONF_LOCKDOWN_DIR "/desktop/gnome/lockdown" -#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 GCONF_LOCKDOWN_PRINT_SETUP "/desktop/gnome/lockdown/disable_print_setup" +#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 GS_SCHEMA_NAME "org.gnome.Evince" -#define GS_OVERRIDE_RESTRICTIONS "override_restrictions" +#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" @@ -244,7 +254,7 @@ struct _EvWindowPrivate { #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) @@ -264,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, @@ -304,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, @@ -326,6 +340,10 @@ 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_update_max_min_scale (EvWindow *window); +#ifdef ENABLE_DBUS +static void ev_window_emit_closed (EvWindow *window); +#endif static guint ev_window_n_copies = 0; @@ -358,7 +376,6 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) const EvDocumentInfo *info = NULL; gboolean has_document = FALSE; gboolean ok_to_print = TRUE; - gboolean ok_to_print_setup = TRUE; gboolean ok_to_copy = TRUE; gboolean has_properties = TRUE; gboolean override_restrictions = TRUE; @@ -398,23 +415,16 @@ 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 (has_document && - gconf_client_get_bool (ev_window->priv->gconf_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 (has_document && - gconf_client_get_bool (ev_window->priv->gconf_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; } - if (has_document && - gconf_client_get_bool (ev_window->priv->gconf_client, GCONF_LOCKDOWN_PRINT_SETUP, NULL)) { - ok_to_print_setup = FALSE; - } -#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); @@ -644,6 +654,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. @@ -887,6 +913,65 @@ ev_window_page_changed_cb (EvWindow *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 update_document_mode (EvWindow *window, EvDocumentMode mode) { @@ -902,18 +987,24 @@ static void setup_chrome_from_metadata (EvWindow *window) { EvChrome chrome = EV_CHROME_NORMAL; - gboolean show_toolbar; + gboolean show_toolbar = TRUE; - if (window->priv->document) { - if (!window->priv->metadata || - !ev_metadata_get_boolean (window->priv->metadata, "show_toolbar", &show_toolbar)) { - show_toolbar = g_settings_get_boolean (window->priv->last_settings, "show-toolbar"); - } + if (ev_window_is_empty (window)) { + window->priv->chrome = chrome; + + return; + } - if (!show_toolbar) - chrome &= ~EV_CHROME_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; } @@ -921,65 +1012,85 @@ static void setup_sidebar_from_metadata (EvWindow *window) { 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; + GSettings *settings = window->priv->default_settings; gchar *page_id; gint sidebar_size; - gboolean sidebar_visibility; + gboolean sidebar_visibility = TRUE; - if (!window->priv->metadata) + if (ev_window_is_empty (window)) return; - if (ev_metadata_get_int (window->priv->metadata, "sidebar_size", &sidebar_size)) { - gtk_paned_set_position (GTK_PANED (window->priv->hpaned), sidebar_size); + 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_get_string (window->priv->metadata, "sidebar_page", &page_id)) { - 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); - } - } 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_get_boolean (window->priv->metadata, "sidebar_visibility", &sidebar_visibility)) - sidebar_visibility = g_settings_get_boolean (window->priv->last_settings, "show-sidebar"); + 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")); + } - update_chrome_flag (window, EV_CHROME_SIDEBAR, sidebar_visibility); - update_chrome_visibility (window); + 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) { - gint page; - gchar *sizing_mode; - gdouble zoom; - gint rotation; - gboolean inverted_colors = FALSE; - gboolean continuous = FALSE; - gboolean dual_page = FALSE; - gboolean fullscreen = FALSE; + 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); - if (!window->priv->metadata) return; + } /* Current page */ if (!window->priv->dest && @@ -994,6 +1105,9 @@ setup_model_from_metadata (EvWindow *window) enum_value = g_enum_get_value_by_nick (g_type_class_peek (EV_TYPE_SIZING_MODE), sizing_mode); ev_document_model_set_sizing_mode (window->priv->model, enum_value->value); + } else if (window->priv->is_new_doc) { + ev_document_model_set_sizing_mode (window->priv->model, + g_settings_get_enum (settings, "sizing-mode")); } /* Zoom */ @@ -1023,25 +1137,37 @@ setup_model_from_metadata (EvWindow *window) } /* Inverted Colors */ - if (ev_metadata_get_boolean (window->priv->metadata, "inverted-colors", &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 (fullscreen) { - ev_window_run_fullscreen (window); - } + 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 @@ -1053,25 +1179,24 @@ setup_document_from_metadata (EvWindow *window) gdouble width_ratio; gdouble height_ratio; - if (!window->priv->metadata) - return; - - /* 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); - setup_sidebar_from_metadata (window); - 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 (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); - g_settings_get (window->priv->last_settings, "window-ratio", "(dd)", &width_ratio, &height_ratio); + 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 */ + } + + 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; @@ -1088,7 +1213,7 @@ setup_document_from_metadata (EvWindow *window) 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) { @@ -1184,8 +1309,7 @@ ev_window_refresh_window_thumbnail (EvWindow *ev_window) 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; } @@ -1211,16 +1335,13 @@ override_restrictions_changed (GSettings *settings, ev_window_setup_action_sensitivity (ev_window); } -#ifdef WITH_GCONF static void -lockdown_changed (GConfClient *client, - guint cnxn_id, - GConfEntry *entry, +lockdown_changed (GSettings *lockdown, + const gchar *key, EvWindow *ev_window) { ev_window_setup_action_sensitivity (ev_window); } -#endif /* WITH_GCONF */ static gboolean ev_window_setup_document (EvWindow *ev_window) @@ -1230,31 +1351,30 @@ ev_window_setup_document (EvWindow *ev_window) GtkAction *action; ev_window->priv->setup_document_idle = 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); - 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); + 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 WITH_GCONF - if (!ev_window->priv->gconf_client) - ev_window->priv->gconf_client = gconf_client_get_default (); - gconf_client_add_dir (ev_window->priv->gconf_client, - GCONF_LOCKDOWN_DIR, - GCONF_CLIENT_PRELOAD_ONELEVEL, - NULL); - gconf_client_notify_add (ev_window->priv->gconf_client, - GCONF_LOCKDOWN_DIR, - (GConfClientNotifyFunc)lockdown_changed, - ev_window, NULL, NULL); -#endif /* WITH_GCONF */ +#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); @@ -1291,6 +1411,8 @@ 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_update_max_min_scale (ev_window); + ev_window_set_message_area (ev_window, NULL); if (ev_document_get_n_pages (document) <= 0) { @@ -1301,6 +1423,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); @@ -1401,6 +1529,8 @@ ev_window_load_job_cb (EvJob *job, if (!ev_job_is_failed (job)) { ev_document_model_set_document (ev_window->priv->model, document); + setup_chrome_from_metadata (ev_window); + update_chrome_actions (ev_window); setup_document_from_metadata (ev_window); setup_view_from_metadata (ev_window); @@ -1858,7 +1988,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; @@ -1870,10 +1999,12 @@ ev_window_open_uri (EvWindow *ev_window, g_object_unref (ev_window->priv->metadata); source_file = g_file_new_for_uri (uri); - if (ev_is_metadata_supported_for_file (source_file)) + if (!ev_file_is_temp (source_file) && ev_is_metadata_supported_for_file (source_file)) { ev_window->priv->metadata = ev_metadata_new (source_file); - else + 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); @@ -1896,6 +2027,7 @@ ev_window_open_uri (EvWindow *ev_window, 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); } @@ -2788,21 +2920,25 @@ ev_window_save_print_settings (EvWindow *window, key_file = get_print_settings_file (); gtk_print_settings_to_key_file (print_settings, key_file, EV_PRINT_SETTINGS_GROUP); - save_print_setting_file (key_file); - g_key_file_free (key_file); - - if (!window->priv->metadata) - return; /* 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 (print_settings, - document_print_settings[i]); - ev_metadata_set_string (window->priv->metadata, - 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 @@ -2813,6 +2949,19 @@ ev_window_save_print_page_setup (EvWindow *window, 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); @@ -3118,6 +3267,7 @@ ev_window_print_range (EvWindow *ev_window, 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); @@ -3169,13 +3319,11 @@ ev_window_print_range (EvWindow *ev_window, ev_print_operation_set_current_page (op, current_page); ev_print_operation_set_print_settings (op, print_settings); ev_print_operation_set_default_page_setup (op, print_page_setup); -#ifdef WITH_GCONF - ev_print_operation_set_embed_page_setup (op, !gconf_client_get_bool (ev_window->priv->gconf_client, - GCONF_LOCKDOWN_PRINT_SETUP, - NULL)); -#else - ev_print_operation_set_embed_page_setup (op, TRUE); -#endif + 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); @@ -3216,6 +3364,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, @@ -3247,29 +3480,18 @@ 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; gint n_print_jobs; - 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); - } - 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, @@ -3300,7 +3522,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, @@ -3320,6 +3542,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 @@ -3735,23 +3987,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 (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); @@ -3902,6 +4178,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) { @@ -4169,6 +4473,7 @@ ev_window_rotation_changed_cb (EvDocumentModel *model, ev_metadata_set_int (window->priv->metadata, "rotation", rotation); + ev_window_update_max_min_scale (window); ev_window_refresh_window_thumbnail (window); } @@ -4314,8 +4619,6 @@ ev_window_view_toolbar_cb (GtkAction *action, EvWindow *ev_window) update_chrome_visibility (ev_window); if (ev_window->priv->metadata) ev_metadata_set_boolean (ev_window->priv->metadata, "show_toolbar", active); - if (ev_window->priv->document) - g_settings_set_boolean (ev_window->priv->last_settings, "show-toolbar", active); } static void @@ -4334,27 +4637,11 @@ 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(); + 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)); } - - g_object_unref (current_page); - - if (ev_window->priv->metadata && !ev_window_is_empty (ev_window)) - ev_metadata_set_string (ev_window->priv->metadata, "sidebar_page", id); } static void @@ -4374,8 +4661,6 @@ ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_sidebar, if (ev_window->priv->metadata) ev_metadata_set_boolean (ev_window->priv->metadata, "sidebar_visibility", visible); - if (ev_window->priv->document) - g_settings_set_boolean (ev_window->priv->last_settings, "show-sidebar", visible); } } @@ -4465,9 +4750,18 @@ view_menu_annot_popup (EvWindow *ev_window, 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 = EV_ANNOTATION_ATTACHMENT (annot)->attachment; + EvAttachment *attachment; + attachment = ev_annotation_attachment_get_attachment (EV_ANNOTATION_ATTACHMENT (annot)); if (attachment) { show_annot = TRUE; if (ev_window->priv->attach_list) { @@ -4562,17 +4856,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; @@ -4806,6 +5106,20 @@ ev_window_dispose (GObject *object) 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; @@ -4816,13 +5130,6 @@ ev_window_dispose (GObject *object) priv->setup_document_idle = 0; } -#ifdef WITH_GCONF - if (priv->gconf_client) { - g_object_unref (priv->gconf_client); - priv->gconf_client = NULL; - } -#endif - if (priv->monitor) { g_object_unref (priv->monitor); priv->monitor = NULL; @@ -4870,9 +5177,15 @@ ev_window_dispose (GObject *object) priv->settings = NULL; } - if (priv->last_settings) { - g_object_unref (priv->last_settings); - priv->last_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; @@ -4943,6 +5256,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, @@ -5045,6 +5363,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) { @@ -5054,6 +5379,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; @@ -5106,6 +5432,8 @@ 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 */ @@ -5252,6 +5580,8 @@ static const GtkActionEntry view_popup_entries [] = { 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 [] = { @@ -5289,6 +5619,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) { @@ -5384,22 +5746,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, @@ -5494,7 +5840,7 @@ window_configure_event_cb (EvWindow *window, GdkEventConfigure *event, gpointer if (window->priv->document) { ev_document_get_max_page_size (window->priv->document, &document_width, &document_height); - g_settings_set (window->priv->last_settings, "window-ratio", "(dd)", + g_settings_set (window->priv->default_settings, "window-ratio", "(dd)", (double)event->width / document_width, (double)event->height / document_height); @@ -5900,6 +6246,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) { @@ -6122,6 +6529,123 @@ get_toolbars_model (void) 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 +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; + + g_variant_get (parameters, "(&s(ii))", &link.filename, &link.line, &link.col); + ev_view_highlight_forward_search (EV_VIEW (window->priv->view), &link); + gtk_window_present (GTK_WINDOW (window)); + } + + 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) { @@ -6133,7 +6657,10 @@ ev_window_init (EvWindow *ev_window) 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); @@ -6142,6 +6669,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; @@ -6304,6 +6860,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, @@ -6319,10 +6893,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 (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_window->priv->password_view = ev_password_view_new (GTK_WINDOW (ev_window)); g_signal_connect_swapped (ev_window->priv->password_view, "unlock", @@ -6346,6 +6919,14 @@ ev_window_init (EvWindow *ev_window) 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); +#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); @@ -6456,7 +7037,8 @@ ev_window_init (EvWindow *ev_window) /* Give focus to the document view */ gtk_widget_grab_focus (ev_window->priv->view); - ev_window->priv->last_settings = g_settings_new (GS_SCHEMA_NAME".Default"); + 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); @@ -6464,7 +7046,7 @@ ev_window_init (EvWindow *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); @@ -6501,3 +7083,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 +}